复合查询与过滤查询的区别,记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架构栈,天天干货都不断哦!

评论 38
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一一哥Sun

您的鼓励是我继续创作的动力哦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值