谷粒商城实战笔记-127-全文检索-ElasticSearch-整合-测试复杂检索

文章目录

  • [一,使用Elasticsearch的Java RESTHighLevel Client完成复杂的查询请求](#一,使用Elasticsearch的Java RESTHighLevel Client完成复杂的查询请求)
    • [1. 创建检索请求 (`SearchRequest`)](#1. 创建检索请求 (SearchRequest))
    • [2. 构造检索条件 (`SearchSourceBuilder`)](#2. 构造检索条件 (SearchSourceBuilder))
    • [3. 执行检索 (`SearchResponse`)](#3. 执行检索 (SearchResponse))
    • [4. 处理解析结果](#4. 处理解析结果)
    • [5. 获取聚合信息](#5. 获取聚合信息)
  • 二,AI时代的效率提升

一,使用Elasticsearch的Java RESTHighLevel Client完成复杂的查询请求

前面es进阶学习中,我们学习过复杂的DSL查询。

dart 复制代码
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();
  • 遍历并处理每个文档:

    java 复制代码
    for (SearchHit searchHit : searchHits) {
        String sourceAsString = searchHit.getSourceAsString();
        Account account = JSON.parseObject(sourceAsString, Account.class);
        System.out.println(account);
    }

5. 获取聚合信息

  • 获取聚合结果:

    • Aggregations aggregations = searchResponse.getAggregations();
  • 处理年龄分布的聚合:

    java 复制代码
    Terms ageAgg1 = aggregations.get("ageAgg");
    for (Terms.Bucket bucket : ageAgg1.getBuckets()) {
        String keyAsString = bucket.getKeyAsString();
        System.out.println("年龄:" + keyAsString + " ==> " + bucket.getDocCount());
    }
  • 处理平均年龄的聚合:

    java 复制代码
    Avg ageAvg1 = aggregations.get("ageAvg");
    System.out.println("平均年龄:" + ageAvg1.getValue());
  • 处理平均薪资的聚合:

    java 复制代码
    Avg balanceAvg1 = aggregations.get("balanceAvg");
    System.out.println("平均薪资:" + balanceAvg1.getValue());

完整代码如下:

dart 复制代码
	/**
     * 复杂检索
     */
    @Test
    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代码了,只需要在测试过程中进行微调即可。

相关推荐
大数据追光猿7 小时前
【大数据Doris】生产环境,Doris主键模型全表7000万数据更新写入为什么那么慢?
大数据·经验分享·笔记·性能优化·doris
sevenez7 小时前
Vibe Coding 实战笔记:从“修好了C坏了AB”到企业级数据库架构重构
c语言·笔记·数据库架构
智嵌电子7 小时前
【笔记篇】【硬件基础篇】模拟电子技术基础 (童诗白) 第10章 模拟电子电路读图
笔记·单片机·嵌入式硬件
2301_800050997 小时前
mysql
数据库·笔记·mysql
QT 小鲜肉8 小时前
【Linux命令大全】001.文件管理之mmove命令(实操篇)
linux·服务器·前端·chrome·笔记
不会学习?8 小时前
markdown笔记分享
经验分享·笔记
QT 小鲜肉8 小时前
【Linux命令大全】001.文件管理之mdel命令(实操篇)
linux·运维·服务器·chrome·笔记
lkbhua莱克瓦2410 小时前
基础-函数
开发语言·数据库·笔记·sql·mysql·函数
yuxb7310 小时前
Kubernetes核心组件详解与实践:Service
笔记·kubernetes
wdfk_prog12 小时前
[Linux]学习笔记系列 -- [fs]kernfs
linux·笔记·学习