springboot2.7集成spring-boot-starter-data-elasticsearch

东郭弘
2023-12-01

文章目录


前言

为了支持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对象语法不报错,但是会报错

 类似资料: