当前位置:   article > 正文

ElasticSearch 8.x 弃用了 High Level REST Client,移除了 Java Transport Client,推荐使用 Elasticsearch Java API_resthighlevelclient被废弃之后官方推荐

resthighlevelclient被废弃之后官方推荐

ElasticSearch

1、ElasticSearch学习随笔之基础介绍
2、ElasticSearch学习随笔之简单操作
3、ElasticSearch学习随笔之java api 操作
4、ElasticSearch学习随笔之SpringBoot Starter 操作
5、ElasticSearch学习随笔之嵌套操作
6、ElasticSearch学习随笔之分词算法
7、ElasticSearch学习随笔之高级检索
8、ELK技术栈介绍
9、Logstash部署与使用
10、ElasticSearch 7.x 版本使用 BulkProcessor 实现批量添加数据
11、ElasticSearch 8.x 弃用了 High Level REST Client,移除了 Java Transport Client,推荐使用 Elasticsearch Java API
12、ElasticSearch 8.x 使用 snapshot(快照)进行数据迁移
13、ElasticSearch 8.x 版本如何使用 SearchRequestBuilder 检索
14、ElasticSearch 8.x 使用 High Level Client 以 HTTPS 方式链接,SSL 证书、主机名验证器 各是什么,如何忽略
15、ElasticSearch 8.x 创建父子文档,用Join类型字段以及用has_child、has_parent 检索

ElasticSearch,创始人 Shay Banon(谢巴农)
本文主要讲解ElasticSearch 高级搜索实战,来满足复杂的业务场景,还是用 Kibana 来操作



前言

最近在公司迁移项目到云服务期间,有一个项目迁移需要升级 ElasticSearch。原先用的是 ElasticSearch 6.8 版本的,迁移到云服务之后由于云服务限制,只能升级到了 ElasticSearch 8.x 版本了,对于一些别依赖来说,比如:jdbc driver、redis client 或者 mq client 可能会有些许 API 变化,所以项目中代码改动不大,但是 ElasticSearch 只要升一级,你的项目中极大可能就是 代码上下一片红,惨不忍睹啊,所以一般非必要不升级啊!

一、ElasticSearch 先后弃用另个客户端

ElasticSearch 7.0.0 版本开始,ElasticSearch 官方就不建议使用 TransportClient 客户端了,推荐使用 High Level REST Client 客户端了。
官方快速通道 ,想了解更多的小伙伴可以移步官方文档,慢慢品读,顺便锻炼英语阅读能力。
ElasticSearch官方通知

The TransportClient is deprecated in favour of the Java High Level REST Client and will be removed in Elasticsearch 8.0.
TransportClient 是不赞成的,推荐使用 Java High Level REST Client,并且将要在 Elasticsearch 8.0 移除


然后接下来,从 ElasticSearch 7.15.0 版本开始,ElasticSearch 官方就不建议使用 High Level REST 客户端了,推荐使用 ElasticSearch-java 客户端了。
官方快速通道 ,想了解更多的小伙伴可以移步官方文档,慢慢品读,顺便锻炼英语阅读能力。

ElasticSearch官方通知
The High Level REST Client is deprecated in favour of the Java API Client。
High Level REST Client是不赞成的,推荐使用 JAVA api 客户端,不过 High Level REST Client 7.17 版本可以和 ElasticSearch 8.x 兼容模式下使用。

一、为什么要弃用 TransportClient 呢?

在 Elasticsearch 7.0.0 版本后不建议使用 TransportClient了,为什么呢?是因为它在分布式集群中的使用方式不够灵活且不够健壮。TransportClient 使用内部集群协议进行通信,这会导致以下问题:

  1. 集群版本兼容问题:Transport Client 必须与 ElasticSearch 集群的确切版本匹配,如果有版本不匹配则会出现兼容问题,对版本特别敏感。
  2. 单点故障:Transport Client 需要连接到特定的节点,如果连接的节点发生故障,客户端则无法自动重新连接到集群的其他节点。
  3. 不推荐的跨版本使用: Transport Client 在集群版本升级时可能会遇到问题,因为它需要与集群完全匹配,跨版本使用会引发不兼容性问题,所以使用还不是很灵活。

但 Transport Client 也有有点的,比如:

  1. 低延迟:与集群内部直接通信,可能具有比 REST 客户端更低的延迟。
  2. 直接与集群通信:能够直接在集群内部进行通信和交互。

所以综合考虑,为了更好地兼容不同版本的集群、更灵活地处理节点故障和更广泛地支持 REST Api,在 ElasticSearch 7.x 版本开始使用 High Level REST Client 进行操作了。

二、为什么要弃用 High Level REST Client 呢?

那在 ElasticSearch 7.15.0 版本开始,官方又不建议使用 High Level REST Client 了,为什么呢?因为它是基于原生的 REST API,而这些 API 在某些情况下限制了某些功能的性能优化。与此同时,官方也推出了 Elasticsearch Java 客户端(Java 客户端)作为替代方案。这个新客户端旨在提供更好的性能、更好的稳定性,并且更易于维护和开发。
缺点如下:

  1. 性能损耗:由于是基于 REST API 的封装,可能存在性能上的一些损耗,比如相比原生的 Java 客户端可能有更高的延迟。
  2. 功能限制:High Level REST Client 对于一些高级或较新的功能可能提供支持不够或者存在一些限制。

优点如下:

  1. 易用性高:High Level REST Client 封装了底层的 REST API,提供了了更直观、更易用的开发方法调用 ElasticSearch 的功能。
  2. 开发效率
  3. 较好的兼容性

虽然 High Level REST Client 在易用性和开发效率方面有优势,但是为了获得更好的性能、更好的稳定性,并且获得更多的特性支持,官方建议从 Elasticsearch 7.15.0 版本开始,使用新的 Java 客户端进行操作。

三、Elasticsearch Java API 如何使用

3.1 pom 依赖

<dependencies>
    <dependency>
        <groupId>co.elastic.clients</groupId>
        <artifactId>elasticsearch-java</artifactId>
        <version>8.7.1</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.12.3</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.22</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

3.2 ES Client 初始化

注意:修改 ES 的用户名密码

/**
 * 初始化客户端
 * @return
 */
private static ElasticsearchClient initClient(){
    String hostname = "192.168.*.*";
    int port = 9200;
    String username = "your username";
    String password = "your password";
    // 基本的用户名密码认证
    BasicCredentialsProvider basicCredentialsProvider = new BasicCredentialsProvider();
    basicCredentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
    RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost(hostname, port, "http"));
    restClientBuilder.setHttpClientConfigCallback(httpAsyncClientBuilder ->
            httpAsyncClientBuilder.setDefaultCredentialsProvider(basicCredentialsProvider));
    RestClient restClient = restClientBuilder.build();
    ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
    ElasticsearchClient esClient = new ElasticsearchClient(transport);
    return esClient;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

3.3 创建 Index

ElasticSearch-java 客户端可以使用连续调用的方式进行编程。

/**
 * 创建索引
 */
private static void createIndex() throws IOException {
    ElasticsearchClient esClient = initClient();
    CreateIndexResponse createIndexResponse = esClient.indices().create(
            new CreateIndexRequest.Builder()
                    .index("product_info")
                    .aliases("product_info_alias",
                            new Alias.Builder().isWriteIndex(true).build()
                    ).build());
    if(createIndexResponse.acknowledged()){
        System.out.println("创建索引成功!");
    } else {
        System.out.println("创建索引失败!");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

3.4 添加数据

定义产品信息实体类 ProductInfo

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ProductInfo {
    private String productName;
    private String productDescription;
    private String color;
    private Integer price;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

ElasticSearch-java 客户端是以 document 的方式添加数据到 ES,这个 document 就是一个 Object 对象,就是把我们创建的实体直接通过写入 Index 中,这样使用起来更加方便。

private static void addData() throws IOException {
    ElasticsearchClient esClient = initClient();
    ProductInfo productInfo = new ProductInfo("红米手机", "红米 Note,智能手机,价格便宜", "蓝色", 999);
    CreateResponse createResponse = esClient.create(createRequest -> createRequest.id("1003").index("product_info").document(productInfo));
    System.out.println("添加索引请求结果:" + createResponse.result());
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3.5 删除数据

以下是比较简单的删除操作,直接通过 ID 进行删除:

private static void delDataVidId(String id) throws IOException {
    ElasticsearchClient esClient = initClient();
    DeleteResponse deleteResponse = esClient.delete(deleteReqest -> deleteReqest.index("product_info").id(id));
    System.out.println("按照 ID 删除索引数据结果:" + deleteResponse.result());
}
  • 1
  • 2
  • 3
  • 4
  • 5

但有时候需要按照某个条件删除,该如何做呢?代码如下:
注意:下面示例是按照条件删除的,比如参数 value 是 “苹果手机”,因为通过 productName 检索会把 “苹果” 和 “手机” 的都检索出来,那样的话就都删除了。

private static void delDataVidQuery(String value) throws IOException {
    ElasticsearchClient esClient = initClient();
    DeleteByQueryResponse deleteByQueryResponse = esClient.deleteByQuery(deleteByQuery -> 
            deleteByQuery.index("product_info").query(query -> 
                    query.match(MatchQuery.of(builder ->
                            builder.field("productName").query(value)))));
    System.out.println("按照条件删除索引数据结果:" + deleteByQueryResponse.deleted());
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

那我们只想删除 “苹果手机” 的数据该如何做呢?其实很简单,以 keyword【productName.keyword】的形式查询就行,代码如下:

private static void delDataVidQuery(String value) throws IOException {
        ElasticsearchClient esClient = initClient();
        DeleteByQueryResponse deleteByQueryResponse = esClient.deleteByQuery(deleteByQuery ->
                deleteByQuery.index("product_info").query(query ->
                        query.match(MatchQuery.of(builder -> builder.queryName("productName.keyword").query(value)))));
        System.out.println("按照条件删除索引数据结果:" + deleteByQueryResponse.deleted());
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3.6 修改数据

下面的示例是通过 ID 修改数据,这种都比较简单:

private static void updateViaId(String id) throws IOException {
        ElasticsearchClient esClient = initClient();
        ProductInfo productInfo = new ProductInfo("苹果手机", "苹果智能手机,价格实惠便宜", "黑色", 5999);
        UpdateResponse<ProductInfo> updateResponse = esClient.update(updateRequest -> updateRequest.index("product_info").id(id).doc(productInfo), ProductInfo.class);
        System.out.println("根据 ID 修改:" + updateResponse.result());
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3.7 查询索引

private static void query(String value) throws IOException {
    ElasticsearchClient esClient = initClient();
    SearchResponse<ProductInfo> searchResponse = esClient.search(searchRequest ->
            searchRequest.index("product_info").query(q -> q.match(MatchQuery.of(builder ->
                    builder.field("productName").query(value)))), ProductInfo.class);
    searchResponse.hits().hits().forEach(productInfoHit -> System.out.println(productInfoHit));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

四、小结

文本主要介绍了 ElasticSearch 弃用 Transport Client 和 High Level REST Client 两个客户端,在 ElasticSearch 8.x 开始官方推荐使用 ElasticSearch-java 客户端了,可在我们的项目中,如果使用 7.x 版本或者更早版本的客户端,那改造起来可不是件容易事情,不过 High Level REST Client 和 ElasticSearch-java 客户端可以兼容模式下一起使用。
对于最新的 ElasticSearch-java 客户端 还有好多操作,比如分页检索、排序等,都有相对应的操作 Request,本文只举几个示例,后面陆续更新。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/754757
推荐阅读
相关标签
  

闽ICP备14008679号