前言
關(guān)于ES的介紹,這里我就不提了,相關(guān)的文章非常多。
Java high-level REST client 是目前官方推薦使用的客戶端,
High Level REST Client 與 Elasticsearch 具有相同的發(fā)布周期。
故我們能夠使用最新版的 Elasticsearch。
Maven
<properties>
...
<es.client.version>6.5.0</es.client.version>
</properties>
...
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>${es.client.version}</version>
<exclusions>
<exclusion>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${es.client.version}</version>
</dependency>
elasticsearch必須要單獨(dú)依賴,否則會(huì)出現(xiàn)如下錯(cuò)誤:
nested exception is java.lang.NoClassDefFoundError: org/elasticsearch/common/xcontent/DeprecationHandler
elasticsearch-rest-high-level-client 6.5集成的是
org.elasticsearch:elasticsearch:5.6.11
5.x版本,并未提供DeprecationHandler類,而是DeprecationRestHandler
如下圖:

Dependencies
為了簡化EsClient的創(chuàng)建流程和多es集群的支持,我寫了一個(gè)構(gòu)造器
public class EsClientBuilder {
private int connectTimeoutMillis = 1000;
private int socketTimeoutMillis = 30000;
private int connectionRequestTimeoutMillis = 500;
private int maxConnectPerRoute = 10;
private int maxConnectTotal = 30;
private final List<HttpHost> httpHosts;
private EsClientBuilder(List<HttpHost> httpHosts) {
this.httpHosts = httpHosts;
}
public EsClientBuilder setConnectTimeoutMillis(int connectTimeoutMillis) {
this.connectTimeoutMillis = connectTimeoutMillis;
return this;
}
public EsClientBuilder setSocketTimeoutMillis(int socketTimeoutMillis) {
this.socketTimeoutMillis = socketTimeoutMillis;
return this;
}
public EsClientBuilder setConnectionRequestTimeoutMillis(int connectionRequestTimeoutMillis) {
this.connectionRequestTimeoutMillis = connectionRequestTimeoutMillis;
return this;
}
public EsClientBuilder setMaxConnectPerRoute(int maxConnectPerRoute) {
this.maxConnectPerRoute = maxConnectPerRoute;
return this;
}
public EsClientBuilder setMaxConnectTotal(int maxConnectTotal) {
this.maxConnectTotal = maxConnectTotal;
return this;
}
public static EsClientBuilder build(List<HttpHost> httpHosts) {
return new EsClientBuilder(httpHosts);
}
public RestHighLevelClient create() {
HttpHost[] httpHostArr = httpHosts.toArray(new HttpHost[0]);
RestClientBuilder builder = RestClient.builder(httpHostArr);
builder.setRequestConfigCallback(requestConfigBuilder -> {
requestConfigBuilder.setConnectTimeout(connectTimeoutMillis);
requestConfigBuilder.setSocketTimeout(socketTimeoutMillis);
requestConfigBuilder.setConnectionRequestTimeout(connectionRequestTimeoutMillis);
return requestConfigBuilder;
});
builder.setHttpClientConfigCallback(httpClientBuilder -> {
httpClientBuilder.setMaxConnTotal(maxConnectTotal);
httpClientBuilder.setMaxConnPerRoute(maxConnectPerRoute);
return httpClientBuilder;
});
return new RestHighLevelClient(builder);
}
}
application.yml
elasticsearch:
nodes: localhost:9200
schema: http
max-connect-total: 50
max-connect-per-route: 10
connection-request-timeout-millis: 500
socket-timeout-millis: 30000
connect-timeout-millis: 1000
然后是Configuration
@Configuration
public class ESConfig {
@Value("${elasticsearch.nodes}")
private List<String> nodes;
@Value("${elasticsearch.schema}")
private String schema;
@Value("${elasticsearch.max-connect-total}")
private Integer maxConnectTotal;
@Value("${elasticsearch.max-connect-per-route}")
private Integer maxConnectPerRoute;
@Value("${elasticsearch.connection-request-timeout-millis}")
private Integer connectionRequestTimeoutMillis;
@Value("${elasticsearch.socket-timeout-millis}")
private Integer socketTimeoutMillis;
@Value("${elasticsearch.connect-timeout-millis}")
private Integer connectTimeoutMillis;
@Bean
public RestHighLevelClient getRestHighLevelClient() {
List<HttpHost> httpHosts = new ArrayList<>();
for (String node : nodes) {
try {
String[] parts = StringUtils.split(node, ":");
Assert.notNull(parts,"Must defined");
Assert.state(parts.length == 2, "Must be defined as 'host:port'");
httpHosts.add(new HttpHost(parts[0], Integer.parseInt(parts[1]), schema));
} catch (RuntimeException ex) {
throw new IllegalStateException(
"Invalid ES nodes " + "property '" + node + "'", ex);
}
}
return EsClientBuilder.build(httpHosts)
.setConnectionRequestTimeoutMillis(connectionRequestTimeoutMillis)
.setConnectTimeoutMillis(connectTimeoutMillis)
.setSocketTimeoutMillis(socketTimeoutMillis)
.setMaxConnectTotal(maxConnectTotal)
.setMaxConnectPerRoute(maxConnectPerRoute)
.create();
}
}
語法和transportclient基本很相似,這里做一下簡單舉例
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.termQuery("field","value"));
boolQueryBuilder.must(QueryBuilders.wildcardQuery("field","value"));
boolQueryBuilder.must(QueryBuilders.rangeQuery("field").gt("value"));
boolQueryBuilder.must(QueryBuilders.termsQuery("field","value"));
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(boolQueryBuilder);
sourceBuilder.sort("field", SortOrder.ASC);
SearchRequest searchRequest = new SearchRequest();
searchRequest.types(esTable.getType());
searchRequest.searchType(SearchType.QUERY_THEN_FETCH);
searchRequest.source(sourceBuilder);
client.search(searchRequest)
如果是cluster,application.yml的nodes設(shè)置多個(gè)ip:host逗號(hào)隔開就可以了。
ps:多個(gè)集群,在application.yml 再定義一組配置,在ESConfig 中創(chuàng)建兩個(gè)name 不同的RestHighLevelClient bean.(暫時(shí)還未嘗試,需要用的同學(xué)可以試試)
作者:流風(fēng)夜雪
郵箱:csycsy2510316@163.com
發(fā)布日期:2019-03-04
更新日期:2019-03-04
歡迎交流。