Elasticsearch入门,超详细2

136 阅读4分钟

六、DSL查询

1. DSL查询分类和基本语法
  • 1.DSL Query的分类

  • 在这里插入图片描述

    1. 查询DSL的基本语法
  • GET /索引库名/_search

  • { "query": { "查询类型": { "FIELD": "TEXT"}}}

  • 举例:

  • GET /hotel/_search
    {
      "query": {
        "match_all": {}
      }
    } 
    
2. 全文检索查询
  • 全文检索查询,会对用户输入内容分词,常用于搜索框搜索

  • match和multi_match的区别是什么

  • match:根据一个字段查询

  • multi_match:根据多个字段查询,参与查询字段越多,查询性能越差

  • 举例:

  •   # match查询
      GET /hotel/_search
      {
        "query": {
          "match": {
            "all": "海滩如家"
          }
        }
      }
    
      # multi_match查询
      GET /hotel/_search
      {
        "query": {
          "multi_match": {
            "query": "外滩如家",
            "fields": ["brand","name","business"]
          }
        }
      }
    
  • 总结:尽量多用match,如果需要多字段查询,尽量使用copy_to去将多个查询字段合并

3. 精确查询
  • 精确查询一般是查找keyword、数值、日期、boolean等类型字段。所以不会对搜索条件分词。

  • # term查询:根据词条精确匹配,一般搜索keyword类型、数值类型、布尔类型、日期类型字段
    GET /hotel/_search
    {
      "query": {
        "term": {
          "city": {
            "value": "上海"
          }
        }
      }
    }
    
    # range查询:根据数值范围查询,可以是数值、日期的范围
    GET /hotel/_search
    {
      "query": {
        "range": {
          "price": {
            "gte": 100,     # gt 大于   gte大于等于
            "lte": 300      # lt 小于   lte小于等于
          }
        }
      }
    }
    
4. 地理查询
  • 根据经纬度查询

  • 第一种:geo_bounding_box:查询geo_point值落在某个矩形范围的所有文档

  • # geo_bounding_box查询
    GET /indexName/_search
    {
      "query": {
        "geo_bounding_box": {
          "FIEID": {
            "top_left": {
              "lat": 31.1,
              "lon": 121.5
            },
            "bottom_right": {
              "lat": 30.9"lon": 121.7
            }
          }
        }
      }
    }
    
  • 第二种:geo_distance:查询到指定中心点小于某个距离值的所有文档

  • # distance查询
    GET /hotel/_search
    {
      "query": {
        "geo_distance": {
          "distance": "15km",
          "location": "31.21,121.5"
        }
      }
    }
    
5. 相关性算分

在这里插入图片描述

6. Funcation Score Query
  • 可以修改文档的相关性算分,根据新得到的算分排序

在这里插入图片描述

  • 举例

  • # function score查询
    GET /hotel/_search
    {
      "query": {
        "function_score": {
          "query": {
            "match": {
              "all": "外滩"
            }
          },
          "functions": [
            {
              "filter": {
                "term": {
                  "brand": "如家"
                }
              },
              "weight": 10
            }
          ],
          "boost_mode": "sum"
        }
      }
    }
    
7. Boolean Query

在这里插入图片描述

  • 举例:搜索名字包含”如家“,价格不高于400,在坐标31.21,121.5周围10km范围内的酒店

  • GET /hotel/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "name": "如家"
              }
            }
          ],
          "must_not": [
            {
              "range": {
                "price": {
                  "gt": 400
                }
              }
            }
          ], 
          "filter": [
            {
            "geo_distance": {
                "distance": "10km",
                "location": {
                  "lat": 31.21,
                  "lon": 121.5
                }
              }
            }
          ]
        }
      }
    }
    # 或者
    GET /hotel/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "name": "如家"
              }
            }
          ],
          "filter": [
            {
              "range": {
                "price": {
                  "gt": 0,
                  "lt": 400
                }
              }
            },
             {
            "geo_distance": {
                "distance": "10km",
                "location": {
                  "lat": 31.21,
                  "lon": 121.5
                }
              }
            }
          ]
        }
      }
    }
    

七、搜索结果处理

1. 排序

在这里插入图片描述

  • 对酒店数据按照用户评价降序排序,评价相同的按照价格升序排序

  • # sort排序
    GET /hotel/_search
    {
      "query": {
        "match_all": {}
      },
      "sort": [
        {
          "score":"desc"
        },
        {
          "price": "asc"
        }
      ]
    }
    
  • 找到121.612282,31.034661周围的酒店,举例升序排序

  • GET /hotel/_search
    {
      "query": {
        "match_all": {}
      },
      "sort": [
        {
          "_geo_distance": {
            "location": {
              "lat": 31.034661,
              "lon": 121.612282
            },
            "order": "asc",
            "unit": "km"
          }
        }
      ]
    }
    
2. 分页

在这里插入图片描述

  • 举例

  • # 分页查询
    GET /hotel/_search
    {
      "query": {
        "match_all": {}
      },
      "sort": [
        {
          "price": "asc"
        }
      ],
      "from": 0,
      "size": 2
    }
    

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3. 高亮

在这里插入图片描述

  • 案例代码

  • # 高亮查询,默认情况下,ES搜索字段必须与高亮字段一致,我们可以
    # 修改属性require_fied_match为false(这样就不必搜索字段和高亮字段一致),默认为true
    GET hotel/_search
    {
      "query": {
        "match": {
          "all": "如家"
        }
      },
      "highlight": {
        "fields": {
          "name": {
            "require_field_match": "false"
          }
        }
      }
    }
    
    4. 总结

    在这里插入图片描述

八、RestClient查询文档

1. 快速入门

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 实例代码

  •     @Test
        void testMatchAll() throws IOException {
            // 1. 准备request
            SearchRequest request = new SearchRequest("hotel");
            // 2. 准备DSL
            request.source().query(QueryBuilders.matchAllQuery());
            // 3. 发送请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    
            // 4. 解析响应
            SearchHits searchHits = response.getHits();
    
            // 4.1 获取总条数
            long total = searchHits.getTotalHits().value;
            System.out.println("共搜索到" + total + "条数据");
            // 4.2 文档数组
            SearchHit[] hits = searchHits.getHits();
            // 4.3 遍历
            for (SearchHit hit : hits) {
                // 获取文档source
                String json = hit.getSourceAsString();
                // 反序列化
                HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
                System.out.println("hotelDoc:" + hotelDoc);
            }
        }
    
2. 通过RestClient进行各种查询
  • 要构建查询条件,只要记住一个类:QueryBuilders

  • 示例代码

  • @Test
       void testMatch() throws IOException {
           // 1. 准备request
           SearchRequest request = new SearchRequest("hotel");
           // 2. 准备DSL
           request.source().query(QueryBuilders.matchQuery("all","如家"));
           // 3. 发送请求
           SearchResponse response = client.search(request, RequestOptions.DEFAULT);
     
           handleResponse(response);
       }
    
    @Test
    void testBool() throws IOException {
        // 1. 准备request
        SearchRequest request = new SearchRequest("hotel");
        // 2. 准备DSL
        // 2.1 准备BooleanQuery
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // 2.2 添加term
        boolQuery.must(QueryBuilders.termQuery("city","上海"));
        // 2.3 添加range
        boolQuery.filter(QueryBuilders.rangeQuery("price").lte(550));
    
        request.source().query(boolQuery);
        // 3. 发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    
        handleResponse(response);
    }
    
    private void handleResponse(SearchResponse response) {
        // 4. 解析响应
        SearchHits searchHits = response.getHits();
        // 4.1 获取总条数
        long total = searchHits.getTotalHits().value;
        System.out.println("共搜索到" + total + "条数据");
        // 4.2 文档数组
        SearchHit[] hits = searchHits.getHits();
        // 4.3 遍历
        for (SearchHit hit : hits) {
            // 获取文档source
            String json = hit.getSourceAsString();
            // 反序列化
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            System.out.println("hotelDoc:" + hotelDoc);
        }
    }
    
3. 排序、分页
    @Test
    void testPageAndSort() throws IOException {
        int page = 1, size = 5;

        // 1. 准备request
        SearchRequest request = new SearchRequest("hotel");
        // 2. 准备DSL
        // 2.1 query
        request.source().query(QueryBuilders.matchAllQuery());
        // 2.2 from、size
        request.source().from((page - 1) * size).size(5);
        // 2.3 sort
        request.source().sort("price", SortOrder.ASC);
        // 3. 发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        handleResponse(response);
    }
4. 高亮显示

在这里插入图片描述

    @Test
    void testHighlight() throws IOException {
        // 1. 准备request
        SearchRequest request = new SearchRequest("hotel");
        // 2. 准备DSL
        // 2.1 query
        request.source().query(QueryBuilders.matchQuery("all", "如家"));
        // 2.2 高亮
        request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
        // 3. 发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        handleResponse(response);
    }

在这里插入图片描述

    private void handleResponse(SearchResponse response) {
        // 4. 解析响应
        SearchHits searchHits = response.getHits();
        // 4.1 获取总条数
        long total = searchHits.getTotalHits().value;
        System.out.println("共搜索到" + total + "条数据");
        // 4.2 文档数组
        SearchHit[] hits = searchHits.getHits();
        // 4.3 遍历
        for (SearchHit hit : hits) {
            // 获取文档source
            String json = hit.getSourceAsString();
            // 反序列化
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            // 获取高亮结果
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if (!CollectionUtils.isEmpty(highlightFields)) {
                // 根据字段名获取高亮结果
                HighlightField highlightField = highlightFields.get("name");
                if (highlightField != null) {
                    // 获取高亮值
                    String name = highlightField.getFragments()[0].string();
                    // 覆盖非高亮结果
                    hotelDoc.setName(name);
                }
            }
            System.out.println("hotelDoc:" + hotelDoc);
        }
    }
5. 组合查询function score

在这里插入图片描述

  • 本篇文章结合黑马课程来做的笔记