Elasticsearch查询must与should不能同层级使用

一、问题现象

最近,在使用es做数据查询时,用了must与should组合查询,发现should下所有条件都不满足得时候,竟然也能查询出来结果。

must和should同时使用,如下例子

{
  "from": 0,
  "size": 20,
  "query": {
    "bool": {
      "must": [
        {
          "term": {"order_id": { "value": 2133456244}}
        },
        {
          "term": {"sku_id": {"value": 1000342267312}}
        }
      ],
      "should": [
        {
          "term": {"creator": {"value": "zhangsanhh"}}
        },
        {
          "terms": {"dept_id_1": [8636,4460]
        }
        }
      ]
    }
  }
}

这时候会发现,当must下的条件都满足的时候,查询结果发现没有满足should下的任何一个条件的数据也包含在结果集内,should好像最小匹配了,变得可有可无了,should or的作用失效了。这显然不是我们想要的查询结果

二、问题分析

原因是我们忽略了隐藏的minimum_should_match参数,表示至少应该匹配的条件数量,其值是数字和百分比均可以。其含义取决于查询中的should 子句的数量。

当取值是整数的时候,表示至少需要匹配的 should 条件数量。当取值是一个百分比时,它表示基于should 条件的总数的相对比例。

在bool查询时候,should是选择性匹配,是or的关系,minimum_should_match默认值是1,也即至少满足一个条件匹配才能查询结果,这个与我们期望的一致。

但是在bool查询下,如果使用must、must_not、filter关键字查询,这时候bool下还带有与之平级的should条件,这时候should条件就失效了,minimum_should_match默认值变为0,should下查询条件满足0个也查询出结果。解决方案有两如下种 

三、解决方案

(1)should降级

一种把should单独包装为一个bool,降级到must下,把其整体作为must下的一个条件查询

{
	"from": 0,
	"size": 20,
	"query": {
		"bool": {
			"must": [{
					"term": {"order_id": {"value": 2133456244}}
				},
				{
					"term": {"sku_id": {"value": 1000342267312}}
				}, {
					"bool": {
						"should": [{
								"term": {"creator": {"value": "zhangsanhh"}}
							},
							{
								"terms": {"dept_id_1": [8636, 4460]}
							}
						]
					}
				}
			]
		}
	}
}

(2)指定minimum_should_match

另一种是在查询中增加minimum_should_match参数,指定值1,表示should下条件要至少满足一个条件的时候才返回数据

{
  "from": 0,
  "size": 20,
  "query": {
    "bool": {
      "must": [
        {
          "term": {"order_id": { "value": 2133456244}}
        }
      ],
      "should": [
        {
          "term": {"creator": {"value": "zhangsanhh"}}
        },
        {
          "terms": {"dept_id_1": [8636,4460]
        }
        }
      ],
       "minimum_should_match": 1,
    }
  }
}

三、总结反思

我们在使用一种不熟悉或者新的技术时候,不要根据对已有中间件的技术点或者经验做类比,要充分理解使用中间件技术点的作用域,做好实地测试。不能忽略中间件的个性。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值