文章目录
一,使用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代码了,只需要在测试过程中进行微调即可。










