SpringBoot2.x 版本集成elasticsearch 8.x(基于elasticsearch-java)

老杨ABC / 2024-10-13 / 原文

  上次elasticsearch到8.13.3之后,由于springboot版本2.4.13,jdk版本是11,使用springboot内置的ElasticsearchRestTemplate查询的时候做了兼容性之后虽然代码没有报错了,但是每次查询都会有一个警告[WRAN],如果查询比较频繁的时候日志里面看到的全都是这种警告信息:[ignore_throttled] parameter is deprecated because frozen indices have been deprecated. Consider cold or frozen tiers in place of frozen indices. 这个警告是什么意思呢?翻译过来就是:[ignore_throttled]参数已被弃用,因为冻结索引已被弃用。考虑用冷层或冻结层代替冻结指数。[ignore_throttled]参数已被弃用 应该是版本的问题,在java中经常会有某个参数在高版本中被废弃使用了。之前我们做的兼容性也没有很好的把各种情况都考虑到,所以我们只有升级客户端了。因为elasticsearch是8.x的,所以在springboot官网也没有找到对应的api版本,并且通过elasticsearch的官网得知,在7.x之后就不在推荐RestHighLevelClient客户端了,用过这个api的人都知道它不管是操作数据还是查询都非常的方便,现在被启用之后,我们也就只有使用Elasticsearch Java API Client了,完整的相关maven jar包如下:
<dependency>
    <groupId>co.elastic.clients</groupId>
    <artifactId>elasticsearch-java</artifactId>
    <version>8.13.3</version>
    <exclusions>
        <exclusion>
            <artifactId>jakarta.json-api</artifactId>
            <groupId>jakarta.json</groupId>
        </exclusion>
        <exclusion>
            <artifactId>elasticsearch-rest-client</artifactId>
            <groupId>org.elasticsearch.client</groupId>
        </exclusion>

    </exclusions>
</dependency>
<!-- https://mvnrepository.com/artifact/org.elasticsearch.client/elasticsearch-rest-client -->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>8.13.3</version>7
</dependency>

<dependency>
    <groupId>jakarta.json</groupId>
    <artifactId>jakarta.json-api</artifactId>
    <version>2.1.2</version>
</dependency>
<dependency>
    <groupId>jakarta.json.bind</groupId>
    <artifactId>jakarta.json.bind-api</artifactId>
    <version>3.0.0</version>
</dependency>

  这里需要注意的是elasticsearch-java的版本号最好是和你的es服务端版本号一致,另外就是要注意rest-client和json的版本号,如果不排除,则默认使用的是springboot里面的,所以这里需要先排除,在重新引用,如果重新应用了还是使用的是sprinboot的内置版本,就需要pom强制修改依赖版了。

<properties>
    <jakarta-json.version>2.1.2</jakarta-json.version>
    <elasticsearch.version>8.13.3</elasticsearch.version>
</properties>

  然后我们再来创建elasticsearch的连接客户端,查询了。

public static void main( String[] args) throws IOException {
    // ES用户名和密码
    String username = "elastic";
    String password = "******";
    BasicCredentialsProvider credsProv = new BasicCredentialsProvider();
    credsProv.setCredentials(
            AuthScope.ANY, new UsernamePasswordCredentials(username, password)
    );
    RestClient restClient = RestClient
            .builder(getHttpHosts())
            .setHttpClientConfigCallback(hc ->
                    hc.setDefaultCredentialsProvider(credsProv)
                            .setKeepAliveStrategy(getConnectionKeepAliveStrategy())
                            .setMaxConnPerRoute(10)
                            .setDefaultIOReactorConfig(IOReactorConfig.custom().setIoThreadCount(1).build())
            )
            .setRequestConfigCallback(requestConfigBuilder ->
                    requestConfigBuilder.setConnectTimeout(1000) //time until a connection with the server is established.
                            .setSocketTimeout(12 * 1000) //time of inactivity to wait for packets[data] to receive.
                            .setConnectionRequestTimeout(2 * 1000)
            ).build();
    ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
    ElasticsearchClient elasticsearchClient = new ElasticsearchClient(transport);

    List<String> gid = new ArrayList<>();
    gid.add("123");//
    gid.add("345");//

    SearchRequest.Builder builder = new SearchRequest.Builder();
    builder.index("es_index_v1");
    BoolQuery.Builder boolQueryBuilder = QueryBuilders.bool();
    //精确查询
    if(true) {
        Query byName = TermQuery.of(m -> m
                .field("goods_name_cms")
                .value("通用商品")
        )._toQuery();
        boolQueryBuilder.must(byName);
    }
    //模糊查询
    if(false){
        boolQueryBuilder.must(query -> query.wildcard(f -> f.field("goods_name_cms").value("*水杯*")));
        Query q = WildcardQuery.of(t->t.field("goods_name_cms").value("*水杯*"))._toQuery();
        boolQueryBuilder.must(q);
    }
    //多文字匹配
    if(false) {
        TermsQuery bySkuIds = TermsQuery.of(t -> t
                .field("goods_id")
                .terms(t2 -> t2
                        .value(gid.stream().map(FieldValue::of).collect(Collectors.toList())))
        );
        boolQueryBuilder.must(bySkuIds._toQuery());
    }
    builder.from(1);
    builder.size(10);
    builder.sort(t->t.field(tt->tt.field("goods_id").order(SortOrder.Desc)));

    BoolQuery boolQuery = boolQueryBuilder.build();
    SearchRequest searchRequest = new SearchRequest.Builder()
            .index("es_good_info_v1_3")
            .query(q -> q.bool(boolQuery))
            .build();


    SearchResponse<EsPhpGoodsIndex> search =
            elasticsearchClient.search(
                    searchRequest,
                    EsPhpGoodsIndex.class
            );
    for (Hit<EsPhpGoodsIndex> hit: search.hits().hits()) {
        EsPhpGoodsIndex pd = hit.source();
        System.out.println(pd);
    }
}

private static HttpHost[] getHttpHosts() {
    List<String> clusterNodes = new ArrayList<>();
    clusterNodes.add("172.0.0.1:9200");
    HttpHost[] httpHosts = new HttpHost[clusterNodes.size()];
    for (int i = 0; i < clusterNodes.size(); i++) {
        String[] node = clusterNodes.get(i).split(":");
        httpHosts[i] = new HttpHost(node[0], Convert.toInt(node[1]), "http");
    }
    return httpHosts;
}

private static ConnectionKeepAliveStrategy getConnectionKeepAliveStrategy() {
    return (response, context) -> 2 * 60 * 1000;
}