复合查询与过滤查询的区别,记ElasticSearch检索时踩过的”坑“!

Posted 一一哥Sun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了复合查询与过滤查询的区别,记ElasticSearch检索时踩过的”坑“!相关的知识,希望对你有一定的参考价值。

一. 背景

对于elasticsearch,想必大家应该都不陌生,它广泛应用于站内搜索,海量数据的处理等业务场景中。本次壹哥不会给大家分享elasticsearch的具体使用教程及性能调优等内容,如果你有兴趣,可以私信我免费获取相关资料。本文主要是给大家聊聊,壹哥在使用ElasticSearch进行业务开发时,曾经遇到过的意想不到的一个”大坑“。

二. bug复现

我们知道,elasticsearch以高效查询著称,主要应用于查询。所以在es中,提供了丰富的查询接口,其中包含了复合查询、过滤查询、分桶聚合、boosting查询、match查询、range查询等各种查询接口。而在这些查询接口中,复合查询与过滤查询是我们比较常用的,也是我们需要特别注意的,因为该接口稍一不注意,就会让你万劫不复,下场很悲惨哦!!!

壹哥先来说下这种查询,当我们需要进行多条件查询时其实就可以使用复合查询,如下所示:

GET es_user/_search

  "query": 
    "bool": 
      "must": [
        
          "match": 
            "address": "北京"
          
        ,
        
          "range": 
            "age": 
              "gte": 10,
              "lte": 300
            
          
        
      ]
    
  

当然我们也可以使用过滤查询,如下所示:


GET es_user/_search

  "query": 
    "bool": 
      "must": [
        
          "match": 
            "address": "湖北"
          
        
      ],
      "filter": [
        
          "range": 
            "age": 
              "gte": 10,
              "lte": 300
            
          
        
      ]
    
  

以上两种查询的结果其实都是一样的,但他们还是有区别的!它们的主要区别在于,复合查询会影响到文档的分数,但过滤查询不会,不信你可以测试一下哦。

不过,这不是壹哥要给大家讲的重点!重点在于我们在使用过滤查询时会出现主条件查不出文档内容,但过滤能过滤出文档列表。

为了能让大家搞清楚这个区别,壹哥给大家展现了如下一个需求:

上图是一个典型的站内搜索需求,具体接口实现如下:


GET es_user/_search

  "query": 
    "bool": 
      "should": [
        
          "match": 
            "goodName": "可口可乐"
          
        
      ],
      "filter": [
        
          "term": 
            "brand": "良品铺子"
          
        
      ]
    
  

 那么问题来了:

当用户在输入框中先输入”可口可乐“,然后点击查询按钮,结果由于索引库中没有”可口可乐“,用户没有查到他想要的内容。接着用户点击了过滤面板中的良品铺子,结果却又能过滤出”可口可乐“这个数据出来,这就不合情理了吧?!用户的主条件没有查询到内容,在过滤时却能出现相关的内容?!任何一个较真的程序员,应该都不会允许这样的情况发生的,这就是bug呀!

三. 问题解决

这个问题曾经也困惑过我,当时壹哥询问过其他人,也查阅过一些资料,最后才发现问题的原因所在。其实要想解决这个问题,我们只需要添加一个查询参数即可,如下所示:

这个参数的意思是,should复合查询条件中必须满足一个条件,才会过滤。也就是说,如果should中一个条件都没有满足,那么就不会过滤。

四. 结语

今天的这篇文章,不知道给各位带来了什么样的启发?有时候一个小小的参数,如果你很熟悉,可能啥问题都不会发生;但如果你不知道,这个小小的参数,却可能会你让你在”大坑“里爬很久都出不来。所以,希望各位在学习的时候,一定要认真对待每一个API,有时候不经意的一个小方法,都足以解决你的大问题。

当然,在你学习的路上,一个好的”老师“,也是非常重要的。一个好的老师知无不言言无不尽,会详细地把各种情况都尽可能地给大家分析预测到,这样才会避免各位少走弯路,避免浪费时间。如果你想遇到一个这样的好老师,可以私信壹哥哦。关注Java架构栈,天天干货都不断哦!

以上是关于复合查询与过滤查询的区别,记ElasticSearch检索时踩过的”坑“!的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB通过许多参数过滤(复合索引与否)

Elasticsearch:深入理解 Elasticsearch 查询:过滤器查询 vs 全文搜索

Elasticsearch:深入理解 Elasticsearch 查询:过滤器查询 vs 全文搜索

Elasticsearch:深入理解 Elasticsearch 查询:过滤器查询 vs 全文搜索

复合条件连接查询

016-elasticsearch-Query DSL-查询上下文,过滤上下文match_all