SpringBoot 实现 elasticsearch 查询操作(RestHighLevelClient 的案例实战)
作者:mmseoamin日期:2023-12-13

文章目录

  • 1. 环境准备
  • 1. 查询全部
  • 2. 根据 name 查询 match 分词查询
  • 3. 根据 name 和 品牌查询 multiMatch 分词查询
  • 4. 根据 brand 查询 match 分词查询
  • 5. 按照价格 范围查询
  • 6. 精确查询
  • 7. boolQuery
  • 8. 分页
  • 9. 高亮查询
  • 9. 公共解析

    SpringBoot 实现 elasticsearch 查询操作(RestHighLevelClient 的案例实战),在这里插入图片描述,第1张


    上一节讲述了 SpringBoot 实现 elasticsearch 索引操作,这一章节讲述 SpringBoot 实现 elasticsearch 查询操作。

    1. 环境准备

    案例用到的索引库结构

    PUT /hotel
    {
      "mappings": {
        "properties": {
          "id": {
            "type": "keyword"
          },
          "name":{
            "type": "text",
            "analyzer": "ik_max_word",
            "copy_to": "all"
          },
          "address":{
            "type": "keyword",
            "index": false
          },
          "price":{
            "type": "integer"
          },
          "score":{
            "type": "integer"
          },
          "brand":{
            "type": "keyword",
            "copy_to": "all"
          },
          "city":{
            "type": "keyword",
            "copy_to": "all"
          },
          "starName":{
            "type": "keyword"
          },
          "business":{
            "type": "keyword"
          },
          "location":{
            "type": "geo_point"
          },
          "pic":{
            "type": "keyword",
            "index": false
          },
          "all":{
            "type": "text",
            "analyzer": "ik_max_word"
          }
        }
      }
    }
    

    1. 查询全部

    @GetMapping("/searchAll")
    public List searchAll() throws Exception {
        //1.创建请求语义对象
        SearchRequest searchRequest = new SearchRequest("索引名称");
        // QueryBuilders: 构建查询类型
        searchRequest.source().query(QueryBuilders.matchAllQuery());
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        return handleResponse(searchResponse);
    }
    

    2. 根据 name 查询 match 分词查询

     @GetMapping("/searchByName/{name}")
    public List searchByName(@PathVariable("name") String name) 
    	throws Exception {
        //1.创建请求语义对象
        SearchRequest searchRequest = new SearchRequest("索引名称");
        // QueryBuilders: 构建查询类型
        searchRequest.source().query(QueryBuilders.matchQuery("name", name));
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        return handleResponse(searchResponse);
    }
    

    3. 根据 name 和 品牌查询 multiMatch 分词查询

    @GetMapping("/searchByNameAndBrand/{name}")
    public List searchByNameAndBrand(@PathVariable("name") String name) throws Exception {
        //1.创建请求语义对象
        SearchRequest searchRequest = new SearchRequest("索引名称");
        // QueryBuilders: 构建查询类型
        searchRequest.source().query(QueryBuilders.multiMatchQuery(name,"name","brand"));
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        return handleResponse(searchResponse);
    }
    

    4. 根据 brand 查询 match 分词查询

    @GetMapping("/searchByBrand/{name}")
    public List searchByBrand(@PathVariable("name") String name) throws Exception {
        //1.创建请求语义对象
        SearchRequest searchRequest = new SearchRequest("索引名称");
        // QueryBuilders: 构建查询类型
        searchRequest.source().query(QueryBuilders.matchQuery("brand", name));
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        return handleResponse(searchResponse);
    }
    

    5. 按照价格 范围查询

     @GetMapping("/searchByPrice/{low}/{high}")
    public List searchByPrice(@PathVariable("low") String low, @PathVariable("high") String high) throws Exception {
        //1.创建请求语义对象
        SearchRequest searchRequest = new SearchRequest("索引名称");
        // QueryBuilders: 构建查询类型
        searchRequest.source().query(QueryBuilders.rangeQuery("price").gte(low).lte(high));
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        return handleResponse(searchResponse);
    }
    

    6. 精确查询

    @GetMapping("/termQueryCity/{city}")
    public List termQueryCity(@PathVariable("city") String city) throws Exception {
        //1.创建请求语义对象
        SearchRequest searchRequest = new SearchRequest("索引名称");
        // QueryBuilders: 构建查询类型
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    	//searchSourceBuilder.query(QueryBuilders.termQuery("city", city)); 这行有点小问题
    	//	https://zhuanlan.zhihu.com/p/270426807 参考
        searchSourceBuilder.query(QueryBuilders.termQuery("city.keyword", city));
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        return handleResponse(searchResponse);
    }
    

    7. boolQuery

    @GetMapping("/testBool")
    public List testBool() throws Exception {
        // 1.准备Request
        SearchRequest request = new SearchRequest("索引名称");
        // 2.准备DSL
        // 2.1.准备BooleanQuery
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // 2.2.添加term
        boolQuery.must(QueryBuilders.termQuery("city.keyword", "杭州"));
        // 2.3.添加range
        boolQuery.filter(QueryBuilders.rangeQuery("price").lte(250));
        request.source().query(boolQuery);
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        return handleResponse(response);
    }
    

    8. 分页

     @GetMapping("/testPageAndSort/{currentPage}/{pageSize}")
    public List testPageAndSort(@PathVariable("currentPage") Integer currentPage, @PathVariable("pageSize") Integer pageSize) throws Exception {
        // 页码,每页大小
        // 1.准备Request
        SearchRequest request = new SearchRequest("索引名称");
        // 2.准备DSL
        // 2.1.query
        request.source().query(QueryBuilders.matchAllQuery());
        // 2.2.排序 sort
        request.source().sort("price", SortOrder.ASC);
        // 2.3.分页 from、size
        request.source().from((currentPage - 1) * pageSize).size(pageSize);
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        return handleResponse(response);
    }
    

    9. 高亮查询

     @GetMapping("/testHighlight/{name}")
    void testHighlight(@PathVariable("name") String name) throws Exception {
        // 1.准备Request
        SearchRequest request = new SearchRequest("索引名称");
        // 2.准备DSL
        // 2.1.query
        request.source().query(QueryBuilders.matchQuery("name", name));
        // 2.2.高亮
        request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        handleResponse2(response);
    }
    

    9. 公共解析

    private List handleResponse(SearchResponse response) throws Exception {
        // 获取命中的所有内容
        SearchHits searchHits = response.getHits();
        // 获取命中的总条数
        long count = searchHits.getTotalHits().value;
        System.out.println("命中的条数为: "+ count);
        // 获取命中的文档对象数组
        SearchHit[] hits = searchHits.getHits();
        List docList = new ArrayList<>();
        for (SearchHit hit : hits) {
            // 解析每一个hit对象得到对应的文档数据
            String json = hit.getSourceAsString();
            //  HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            docList.add(JSON.parseObject(json, HotelDoc.class));
        }
        //destroy();
        return docList;
    }
    private void handleResponse2(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 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);
        }
    }
    

    SpringBoot 实现 elasticsearch 查询操作(RestHighLevelClient 的案例实战),在这里插入图片描述,第2张