文章目录
- 一,使用Elasticsearch的Java RESTHighLevel Client完成复杂的查询请求
- 1. 创建检索请求 (`SearchRequest`)
- 2. 构造检索条件 (`SearchSourceBuilder`)
- 3. 执行检索 (`SearchResponse`)
- 4. 处理解析结果
- 5. 获取聚合信息
- 二,AI时代的效率提升
一,使用Elasticsearch的Java RESTHighLevel Client完成复杂的查询请求
前面es进阶学习中,我们学习过复杂的DSL查询。
POST bank/_search
{
"query": {
"match": {
"address": {
"query": "Mill"
}
}
},
"aggregations": {
"ageAgg": {
"terms": {
"field": "age",
"size": 10
}
},
"ageAvg": {
"avg": {
"field": "age"
}
},
"balanceAvg": {
"avg": {
"field": "balance"
}
}
}
}
如何使用Java客户端执行复杂的查询呢?
使用Elasticsearch的Java REST High-Level Client执行一个复杂的带有聚合的搜索请求。
1. 创建检索请求 (SearchRequest
)
-
创建
SearchRequest
对象:SearchRequest searchRequest = new SearchRequest();
-
指定索引:
searchRequest.indices("bank");
2. 构造检索条件 (SearchSourceBuilder
)
-
创建
SearchSourceBuilder
对象:SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
-
设置查询条件:
sourceBuilder.query(QueryBuilders.matchQuery("address", "Mill"));
-
添加聚合:
-
按年龄分组的聚合:
TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg").field("age").size(10);
sourceBuilder.aggregation(ageAgg);
-
计算平均年龄:
AvgAggregationBuilder ageAvg = AggregationBuilders.avg("ageAvg").field("age");
sourceBuilder.aggregation(ageAvg);
-
计算平均薪资:
AvgAggregationBuilder balanceAvg = AggregationBuilders.avg("balanceAvg").field("balance");
sourceBuilder.aggregation(balanceAvg);
-
-
打印检索条件:
System.out.println("检索条件:" + sourceBuilder);
-
将检索条件添加到
SearchRequest
中:searchRequest.source(sourceBuilder);
3. 执行检索 (SearchResponse
)
-
执行搜索请求:
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
-
打印检索结果:
System.out.println("检索结果:" + searchResponse);
4. 处理解析结果
-
获取搜索命中的文档:
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
-
遍历并处理每个文档:
-
for (SearchHit searchHit : searchHits) { String sourceAsString = searchHit.getSourceAsString(); Account account = JSON.parseObject(sourceAsString, Account.class); System.out.println(account); }
-
5. 获取聚合信息
-
获取聚合结果:
Aggregations aggregations = searchResponse.getAggregations();
-
处理年龄分布的聚合:
-
Terms ageAgg1 = aggregations.get("ageAgg"); for (Terms.Bucket bucket : ageAgg1.getBuckets()) { String keyAsString = bucket.getKeyAsString(); System.out.println("年龄:" + keyAsString + " ==> " + bucket.getDocCount()); }
-
-
处理平均年龄的聚合:
-
Avg ageAvg1 = aggregations.get("ageAvg"); System.out.println("平均年龄:" + ageAvg1.getValue());
-
-
处理平均薪资的聚合:
-
Avg balanceAvg1 = aggregations.get("balanceAvg"); System.out.println("平均薪资:" + balanceAvg1.getValue());
-
完整代码如下:
/**
* 复杂检索
*/
public void searchData() throws IOException {
//1. 创建检索请求
SearchRequest searchRequest = new SearchRequest();
//1.1)指定索引
searchRequest.indices("bank");
//1.2)构造检索条件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
sourceBuilder.query(QueryBuilders.matchQuery("address", "Mill"));
//1.2.1)按照年龄分布进行聚合
TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg").field("age").size(10);
sourceBuilder.aggregation(ageAgg);
//1.2.2)计算平均年龄
AvgAggregationBuilder ageAvg = AggregationBuilders.avg("ageAvg").field("age");
sourceBuilder.aggregation(ageAvg);
//1.2.3)计算平均薪资
AvgAggregationBuilder balanceAvg = AggregationBuilders.avg("balanceAvg").field("balance");
sourceBuilder.aggregation(balanceAvg);
System.out.println("检索条件:" + sourceBuilder);
searchRequest.source(sourceBuilder);
//2. 执行检索
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
System.out.println("检索结果:" + searchResponse);
//3. 将检索结果封装为Bean
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit searchHit : searchHits) {
String sourceAsString = searchHit.getSourceAsString();
Account account = JSON.parseObject(sourceAsString, Account.class);
System.out.println(account);
}
//4. 获取聚合信息
Aggregations aggregations = searchResponse.getAggregations();
Terms ageAgg1 = aggregations.get("ageAgg");
for (Terms.Bucket bucket : ageAgg1.getBuckets()) {
String keyAsString = bucket.getKeyAsString();
System.out.println("年龄:" + keyAsString + " ==> " + bucket.getDocCount());
}
Avg ageAvg1 = aggregations.get("ageAvg");
System.out.println("平均年龄:" + ageAvg1.getValue());
Avg balanceAvg1 = aggregations.get("balanceAvg");
System.out.println("平均薪资:" + balanceAvg1.getValue());
}
二,AI时代的效率提升
相对于DSL,使用Java客户端来完成复杂的请求,代码是比较复杂不好理解的。
DSL相对清晰、容易理解。
所以,我们可以先根据需求,写好DSL,然后用大模型工具比如通义千问、Kimi、ChatGPT等将DSL转换为Java代码,这样我们就无需逐行编写复杂难懂的Java代码了,只需要在测试过程中进行微调即可。