赞
踩
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 7.0.0
版本开始,ElasticSearch 官方就不建议使用 TransportClient 客户端了,推荐使用 High Level REST Client 客户端了。
官方快速通道 ,想了解更多的小伙伴可以移步官方文档,慢慢品读,顺便锻炼英语阅读能力。
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 客户端了。
官方快速通道 ,想了解更多的小伙伴可以移步官方文档,慢慢品读,顺便锻炼英语阅读能力。
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 兼容模式下使用。
在 Elasticsearch 7.0.0 版本后不建议使用 TransportClient了,为什么呢?是因为它在分布式集群中的使用方式不够灵活且不够健壮。TransportClient 使用内部集群协议进行通信,这会导致以下问题:
但 Transport Client 也有有点的,比如:
所以综合考虑,为了更好地兼容不同版本的集群、更灵活地处理节点故障和更广泛地支持 REST Api,在 ElasticSearch 7.x 版本开始使用 High Level REST Client 进行操作了。
那在 ElasticSearch 7.15.0 版本开始,官方又不建议使用 High Level REST Client 了,为什么呢?因为它是基于原生的 REST API,而这些 API 在某些情况下限制了某些功能的性能优化。与此同时,官方也推出了 Elasticsearch Java 客户端(Java 客户端)作为替代方案。这个新客户端旨在提供更好的性能、更好的稳定性,并且更易于维护和开发。
缺点如下:
优点如下:
虽然 High Level REST Client 在易用性和开发效率方面有优势,但是为了获得更好的性能、更好的稳定性,并且获得更多的特性支持,官方建议从 Elasticsearch 7.15.0 版本开始,使用新的 Java 客户端进行操作。
<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>
注意
:修改 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; }
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("创建索引失败!"); } }
定义产品信息实体类 ProductInfo :
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ProductInfo {
private String productName;
private String productDescription;
private String color;
private Integer price;
}
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());
}
以下是比较简单的删除操作,直接通过 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());
}
但有时候需要按照某个条件删除,该如何做呢?代码如下:
注意
:下面示例是按照条件删除的,比如参数 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());
}
那我们只想删除 “苹果手机” 的数据该如何做呢?其实很简单,以 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());
}
下面的示例是通过 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());
}
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));
}
文本主要介绍了 ElasticSearch 弃用 Transport Client 和 High Level REST Client 两个客户端,在 ElasticSearch 8.x 开始官方推荐使用 ElasticSearch-java 客户端了,可在我们的项目中,如果使用 7.x 版本或者更早版本的客户端,那改造起来可不是件容易事情,不过 High Level REST Client 和 ElasticSearch-java 客户端可以兼容模式下一起使用。
对于最新的 ElasticSearch-java 客户端 还有好多操作,比如分页检索、排序等,都有相对应的操作 Request,本文只举几个示例,后面陆续更新。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。