前言
关于ES的介绍,这里我就不提了,相关的文章非常多。
Java high-level REST client 是目前官方推荐使用的客户端,
High Level REST Client 与 Elasticsearch 具有相同的发布周期。
故我们能够使用最新版的 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必须要单独依赖,否则会出现如下错误:
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
如下图:
为了简化EsClient的创建流程和多es集群的支持,我写了一个构造器
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设置多个ip:host逗号隔开就可以了。
ps:多个集群,在application.yml 再定义一组配置,在ESConfig 中创建两个name 不同的RestHighLevelClient bean.(暂时还未尝试,需要用的同学可以试试)
作者:流风夜雪
邮箱:csycsy2510316@163.com
发布日期:2019-03-04
更新日期:2019-03-04
欢迎交流。
网友评论