美文网首页
elasticsearch之十六springboot测试文档过滤

elasticsearch之十六springboot测试文档过滤

作者: Java及SpringBoot | 来源:发表于2020-04-01 10:36 被阅读0次

    个人专题目录](https://www.jianshu.com/p/140e2a59db2c)


    1. elasticsearch文档过滤查询结果

    1.1 filter与query对比

    filter,仅仅只是按照搜索条件过滤出需要的数据而已,不计算任何相关度分数,对相关度没有任何影响;
    query,会去计算每个document相对于搜索条件的相关度,并按照相关度进行排序;

    一般来说,如果你是在进行搜索,需要将最匹配搜索条件的数据先返回,那么用query;如果你只是要根据一些条件筛选出一部分数据,不关注其排序,那么用filter;
    除非是你的这些搜索条件,你希望越符合这些搜索条件的document越排在前面返回,那么这些搜索条件要放在query中;如果你不希望一些搜索条件来影响你的document排序,那么就放在filter中即可;

    1.2 filter与query性能对比

    filter,不需要计算相关度分数,不需要按照相关度分数进行排序,同时还有内置的自动cache最常使用filter的数据

    query,相反,要计算相关度分数,按照分数进行排序,而且无法cache结果.

    ElasticSearch提供了一种特殊的缓存,即过滤器缓存(filter cache),用来存储过滤器的结果,被缓存的过滤器并不需要消耗过多的内存(因为它们只存储了哪些文档能与过滤器相匹配的相关信息),而且可供后续所有与之相关的查询重复使用,从而极大地提高了查询性能。

    1.3 filter

    POST /book-index/_search
    {
      "query": {
        "bool": {
          "filter": [
            {
              "term": {
                "brandName": {
                  "value": "飞利浦",
                  "boost": 1
                }
              }
            },
            {
              "term": {
                "categoryName": {
                  "value": "手机",
                  "boost": 1
                }
              }
            }
          ],
          "adjust_pure_negative": true,
          "boost": 1
        }
      }
    }
    
    @Override
    public void filterInBoolQuery(String indexName) throws Exception {
        SearchRequest searchRequest = new SearchRequest(indexName);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.filter(QueryBuilders.termQuery("brandName", "飞利浦"));
        queryBuilder.filter(QueryBuilders.termQuery("categoryName", "手机"));
        baseQuery.builder(indexName, queryBuilder);
    }
    

    1.4 range过滤器

    range过滤器允许我们将搜索范围限制在字段值给定的界限范围内。

    POST /book-index/_search
    {
      "from": 0,
      "size": 100,
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "title": {
                  "query": "三星",
                  "operator": "OR",
                  "prefix_length": 0,
                  "max_expansions": 50,
                  "fuzzy_transpositions": true,
                  "lenient": false,
                  "zero_terms_query": "NONE",
                  "auto_generate_synonyms_phrase_query": true,
                  "boost": 1
                }
              }
            }
          ],
          "filter": [
            {
              "range": {
                "price": {
                  "from": 2000,
                  "to": 3000,
                  "include_lower": true,
                  "include_upper": true,
                  "boost": 1
                }
              }
            }
          ],
          "must_not": [
            {
              "term": {
                "brandName": {
                  "value": "诺基亚",
                  "boost": 1
                }
              }
            }
          ],
          "should": [
            {
              "term": {
                "categoryName": {
                  "value": "手机",
                  "boost": 1
                }
              }
            },
            {
              "term": {
                "categoryName": {
                  "value": "平板电视",
                  "boost": 1
                }
              }
            }
          ],
          "adjust_pure_negative": true,
          "boost": 1
        }
      }
    }
    
    @Override
    public void rangeQuery(String indexName, String fieldName, int from, int to) throws Exception {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.should(QueryBuilders.termQuery("categoryName", "手机"));
        queryBuilder.should(QueryBuilders.termQuery("categoryName", "平板电视"));
        queryBuilder.must(QueryBuilders.matchQuery("title", "三星"));
        queryBuilder.mustNot(QueryBuilders.termQuery("brandName", "诺基亚"));
        queryBuilder.filter(QueryBuilders.rangeQuery(fieldName).from(from).to(to));
        baseQuery.builder(indexName, queryBuilder);
    }
    
    @Test
    public void testRangeCardQuery() throws Exception {
        filterQuery.rangeQuery(indexName,"price",1,5);
    }
    

    1.5 exists 过滤器

    exists 过滤器只选择给定字段的文档。如果某字段没有值,就不选择。

    比如我们查询响应时间不为空的文档:

    POST /book-index/_search
    {
      "query": {
        "exists": {
          "field": "title",
          "boost": 1
        }
      }
    }
    
    @Override
    public void existQuery(String indexName, String fieldName) throws Exception {
        baseQuery.builder(indexName, QueryBuilders.existsQuery(fieldName));
    }
    
    @Test
    public void testExistQuery() throws IOException {
        Goods goods = new Goods();
        goods.setId(1);
        //goods.setTitle("new2 - 阿尔卡特 (OT-927) 炭黑 联通3G手机 双卡双待");
        goods.setPrice(22.32);
        goods.setStock(23232);
        goods.setSaleNum(32);
        goods.setCreateTime(new Date());
        goods.setCategoryName("平板电视");
        goods.setBrandName("三星");
        goods.setSpecStr("{\"电视屏幕尺寸\":\"46英寸\"}");
        docService.addDoc(Constants.INDEX_NAME, objectMapper.writeValueAsString(goods), "1");
        filterQuery.existQuery(Constants.INDEX_NAME, "title");
    }
    

    相关文章

      网友评论

          本文标题:elasticsearch之十六springboot测试文档过滤

          本文链接:https://www.haomeiwen.com/subject/pddouhtx.html