• ElasticSearch - 基于 JavaRestClient 查询文档(match、精确、复合查询,以及排序、分页、高亮)


    目录

    一、基于 JavaRestClient 查询文档

    1.1、查询 API 演示

    1.1.1、查询基本框架

    DSL 请求的对应格式

    响应的解析

    1.1.2、全文检索查询

    1.1.3、精确查询

    1.1.4、复合查询

    1.1.5、排序和分页

    1.1.6、高亮


    一、基于 JavaRestClient 查询文档


    1.1、查询 API 演示

    1.1.1、查询基本框架

    接下里通过一个 match_all 查询所有,来演示以下基本的 API.

    1. @Test
    2. public void testMatchAll() throws IOException {
    3. //1.准备 SearchRequest
    4. SearchRequest request = new SearchRequest("hotel");
    5. //2.准备参数
    6. request.source().query(QueryBuilders.matchAllQuery());
    7. //3.发送请求,并接收响应
    8. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    9. //4.解析响应
    10. handlerResponse(response);
    11. }
    12. /**
    13. * 处理响应
    14. * @param response
    15. */
    16. private void handlerResponse(SearchResponse response) {
    17. //1.解析结果
    18. SearchHits hits = response.getHits();
    19. //获取总条数
    20. long total = hits.getTotalHits().value;
    21. SearchHit[] hits1 = hits.getHits();
    22. for(SearchHit searchHit : hits1) {
    23. //获取source
    24. String json = searchHit.getSourceAsString();
    25. System.out.println(json);
    26. }
    27. }

    由上可以看出查询的基本步骤如下:

    1. 创建 SeaechRequest 对象,指定索引库.
    2. Request.source() 准备参数,也就是 DSL.
      1. 通过 QueryBuilders 构建查询条件.
      2. 传入 Request.source() 的 query() 方法,构建好完整的查询.
    3. 发送请求,得到结果.
    4. 解析结果(又外而内,逐层解析).

    DSL 请求的对应格式

    DSL 语句的构建是通过 HighLevelRestClient 中的 Resource 实现的,其中包含了 查询、排序】分页、高亮等所有功能.

    其中  query 表示查询的意思,他的查询条件的是由 QueryBuilders 的工具类提供的,包含了各种查询方法.

    响应的解析

    响应解析这里,可以在 Kibana 上通过查询结果,对比着看出 API 的调用关系.

    1.1.2、全文检索查询

    全文检索的 match 和 multi_match 查询和前面演示的 match_all 调用的 API 基本一致,差别就是查询条件,也就是 query 部分(通过 QueryBuilders 构建的条件不一样).

    1. @Test
    2. public void testMatch() throws IOException {
    3. //1.准备 SearchRequest
    4. SearchRequest request = new SearchRequest("hotel");
    5. //2.准备参数
    6. request.source().query(QueryBuilders.matchQuery("brand", "如家"));
    7. //3.发送请求,并接收响应
    8. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    9. //4.解析响应
    10. handlerResponse(response);
    11. }

    multi_match 也是如此,只是可以支持多个参数查询.

    1. @Test
    2. public void testMultiMatch() throws IOException {
    3. //1.准备 SearchRequest
    4. SearchRequest request = new SearchRequest("hotel");
    5. //2.准备参数
    6. request.source().query(QueryBuilders.multiMatchQuery("如家", "brand", "name"));
    7. //3.发送请求,并接收响应
    8. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    9. //4.解析响应
    10. handlerResponse(response);
    11. }

    运行结果:

    1.1.3、精确查询

    精确查询常见的有 term 查询 和 range 查询,同样利用 QueryBuilders 实现.

    1. @Test
    2. public void testTerm() throws IOException {
    3. //1.准备 SearchRequest
    4. SearchRequest request = new SearchRequest("hotel");
    5. //2.准备参数
    6. request.source().query(QueryBuilders.termQuery("city", "上海"));
    7. //3.发送请求,并接收响应
    8. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    9. //4.解析响应
    10. handlerResponse(response);
    11. }

    range 查询也是如此.

    1. @Test
    2. public void testRange() throws IOException {
    3. //1.准备 SearchRequest
    4. SearchRequest request = new SearchRequest("hotel");
    5. //2.准备参数
    6. request.source().query(QueryBuilders.rangeQuery("price").gte(100).lte(200)); //链式调用
    7. //3.发送请求,并接收响应
    8. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    9. //4.解析响应
    10. handlerResponse(response);
    11. }

    1.1.4、复合查询

    布尔查询是一个或多个查询子句的组合. 子查询的组合方式有:

    • must:必须匹配的查询条件,类似 “与”.
    • should:选择性匹配的查询条件,类似 “或”.
    • must_not:必须不匹配,不参与算分,类似 “非”.
    • filter:必须匹配,不参与算分

    RestAPI 中也提供 BoolQueryBuilder 条件构建方法,用来添加上述条件.

    1. @Test
    2. public void testBoolQuery() throws IOException {
    3. //1.准备 SearchRequest
    4. SearchRequest request = new SearchRequest("hotel");
    5. //2.准备参数
    6. BoolQueryBuilder booleanQuery = QueryBuilders.boolQuery();
    7. booleanQuery.must(QueryBuilders.termQuery("city", "上海"));
    8. booleanQuery.filter(QueryBuilders.rangeQuery("price").lte("200"));
    9. request.source().query(booleanQuery); //链式调用
    10. //3.发送请求,并接收响应
    11. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    12. //4.解析响应
    13. handlerResponse(response);
    14. }

    1.1.5、排序和分页

    对于搜索结果的排序和分页与  query 是同级参数,对应 API 如下.

    1. @Test
    2. public void testFromSize() throws IOException {
    3. //1.准备 SearchRequest
    4. SearchRequest request = new SearchRequest("hotel");
    5. //2.准备参数
    6. request.source().query(QueryBuilders.matchAllQuery());
    7. //分页 offset=20 size=10
    8. request.source().from(20).size(10);
    9. //降序排序
    10. request.source().sort("price", SortOrder.DESC);
    11. //3.发送请求,并接收响应
    12. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    13. //4.解析响应
    14. handlerResponse(response);
    15. }

    1.1.6、高亮

    高亮的  API 包括请求构建 DSL 语句 和 结果解析 两个部分.

    请求构建如下:

    1. @Test
    2. public void testHighLighter() throws IOException {
    3. //1.准备 SearchRequest
    4. SearchRequest request = new SearchRequest("hotel");
    5. //2.准备参数
    6. request.source().query(QueryBuilders.matchQuery("brand", "如家"));
    7. request.source().highlighter(new HighlightBuilder()
    8. .field("name")
    9. .requireFieldMatch(false));
    10. //3.发送请求,并接收响应
    11. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    12. //4.解析响应
    13. handlerResponse(response);
    14. }

    响应解析如下 :

    1. private void handlerResponse(SearchResponse response) throws JsonProcessingException {
    2. //1.解析结果
    3. SearchHits hits = response.getHits();
    4. //获取总条数
    5. long total = hits.getTotalHits().value;
    6. SearchHit[] hits1 = hits.getHits();
    7. for(SearchHit searchHit : hits1) {
    8. //获取source
    9. String json = searchHit.getSourceAsString();
    10. System.out.println(json);
    11. //2.处理高亮
    12. //获取高亮
    13. Map highlightFieldMap = searchHit.getHighlightFields();
    14. if(!CollectionUtils.isEmpty(highlightFieldMap)) {
    15. //获取高亮字段的 value
    16. HighlightField highlightField = highlightFieldMap.get("name");
    17. if(highlightField != null) {
    18. //取出高亮结果数组中的第一个,这里是酒店名称
    19. String name = highlightField.getFragments()[0].string();
    20. //对高亮字段的处理(这里打印做演示)
    21. System.out.println(name);
    22. }
    23. }
    24. }
    25. }

    运行后可以看到通过 sout 打印出的“高亮”字段(最后会传输给前端 ,让前端处理高亮. 后端只是标记出了哪些字段需要高亮处理)

  • 相关阅读:
    [Redis] Redis实战--EVAL
    主机dbeaver访问gitlab容器中的pg
    击败GPT4-Turbo,最强开源代码模型DeepSeek-Coder-V2问世
    苹果开源高效语言模型 OpenELM;全球首个 AI 基因编辑器开源丨RTE 开发者日报 Vol.192
    跟单王订单追踪软件如何打通金蝶ERP?
    路由知识——路由分类+RIP相关知识+链路状态协议和距离矢量协议的区别
    基于ATL的Com服务注册后被调用,CoCreateInstance返回0x80080005,服务启动失败
    Roson的Qt之旅#100 QML四种标准对话框(颜色、字体、文件、提升)
    迁移学习怎么用
    JUC05-AQS、ReentrantLock原理
  • 原文地址:https://blog.csdn.net/CYK_byte/article/details/133296107