elasticsearch之十六springboot测试文档过滤查询结果

个人专题目录](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");
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容