前言
为了支持Elasticsearch Java API客户端,不推荐使用High Level Rest客户端,所以新的elasticsearch用法和配置和以前不是特别一样
一、配置文件
spring.elasticsearch.uris=xxxxx:9200
spring.elasticsearch.password=xxxx
spring.elasticsearch.username=xxx
spring.elasticsearch.connection-timeout=10s
spring.elasticsearch.read-timeout=30s
二、注入elasticsearch客户端到springioc
1.创建ElasticSearchConfig配置对象
代码如下(示例):
@Configuration
public class ElasticSearchConfig extends ElasticsearchConfigurationSupport {
@Resource
private ElasticsearchProperties elasticSearchProperty;
@Bean
public RestClientBuilder restClientBuilder() {
return RestClient.builder(elasticSearchProperty.getUris().stream().map(this::getElasticSearchHttpHosts).toArray(HttpHost[]::new)).
setRequestConfigCallback(requestConfigBuilder -> {
//设置连接超时时间
requestConfigBuilder.setConnectTimeout(elasticSearchProperty.getConnectionTimeout().toMillisPart());
requestConfigBuilder.setSocketTimeout(elasticSearchProperty.getSocketTimeout().toMillisPart());
return requestConfigBuilder;
}).setFailureListener(new RestClient.FailureListener() {
//某节点失败,这里可以做一些告警
@Override
public void onFailure(Node node) {
LogUtil.error("[ ElasticSearchClient ] >> node :{}, host:{}, fail ", node.getName(), node.getHost());
}
}).setHttpClientConfigCallback(httpClientBuilder -> {
httpClientBuilder.disableAuthCaching();
//设置账密
return getHttpAsyncClientBuilder(httpClientBuilder);
});
}
/**
* 配置es client
*/
@Bean(value = "elasticsearchClient")
public ElasticsearchClient elasticsearchClient(@Qualifier("restClientBuilder") RestClientBuilder restClientBuilder) {
RestClient restClient = restClientBuilder.setDefaultHeaders(new Header[]{new BasicHeader("Content-Type", "application/vnd.elasticsearch+json"),}).build();
ElasticsearchTransport transport = new RestClientTransport(
restClient, new JacksonJsonpMapper());
return new ElasticsearchClient(transport);
}
@Bean(value = "elasticsearchTemplate")
public ElasticsearchTemplate elasticsearchTemplate(ElasticsearchClient elasticsearchClient, ElasticsearchConverter elasticsearchConverter) {
return new ElasticsearchTemplate(elasticsearchClient, elasticsearchConverter);
}
private HttpHost getElasticSearchHttpHosts(String host) {
host = host.replaceAll("http://", "").replaceAll("https://", "");
return new HttpHost(host.split(":")[0], Integer.parseInt(host.split(":")[1]), "http");
}
private HttpAsyncClientBuilder getHttpAsyncClientBuilder(HttpAsyncClientBuilder httpClientBuilder) {
if (StringUtils.isEmpty(elasticSearchProperty.getUsername()) || StringUtils.isEmpty(elasticSearchProperty.getPassword())) {
return httpClientBuilder;
}
//设置账号密码
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(elasticSearchProperty.getUsername(), elasticSearchProperty.getPassword()));
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
return httpClientBuilder;
}
}
2.使用ElasticsearchTemplate操作es
这里需要注意,新版本中使用ElasticsearchTemplate而不是ElasticsearchRestTemplate
1.构建查询对象,查询name为张三的
/**
* 当前函数查询第一页 每页显示100条数据,并且name有张三的数据
*/
public void testSearch(){
BoolQuery.Builder boolQueryBuilder = new BoolQuery.Builder();
boolQueryBuilder.must(new co.elastic.clients.elasticsearch._types.query_dsl.Query.Builder().term(new TermQuery.Builder().value(FieldValue.of("张三")).field("name").build()).build());
co.elastic.clients.elasticsearch._types.query_dsl.Query build = new co.elastic.clients.elasticsearch._types.query_dsl.Query.Builder().bool(boolQueryBuilder.build()).build();
NativeQueryBuilder query = new NativeQueryBuilder()
.withPageable(PageRequest.of(1, 100))
.withQuery(build)
.withSourceFilter(new FetchSourceFilter(new String[]{}, new String[]{"@version", "@timestamp", "host", "tags"}))
.withAggregation("count", new Aggregation.Builder().valueCount(new ValueCountAggregation.Builder().field("_id").build()).build());
SearchHits<Object> test = elasticsearchTemplate.search(query.build(), Object.class, IndexCoordinates.of("test"));
}
注意新的api里面,查询对象不是NativeSearchQuery而是NativeQuery对象,如果使用
ElasticsearchTemplate----------->NativeQuery 新
ElasticsearchRestTemplate------>NativeSearchQuery 旧
总结
这里的操作Elasticsearch的Api发生了较大的变化,使用的时候需要注意。
java.lang.IllegalArgumentException: unhandled Query implementation NativeSearchQuery
这里是因为ElasticsearchTemplate需要使用新的NativeQuery对象,虽然使用旧的NativeSearchQuery对象语法不报错,但是会报错