Elasticsearch嵌套对象复杂布尔查询结果异常排查
我来帮你梳理下问题出在哪,再给出符合预期的查询方案:
先分析你之前的查询错误
第一个查询的问题
你最初的must_not里放了三个独立的nested查询,这相当于告诉Elasticsearch:排除所有收到过c2、或c3、或c4中任意一个活动的收件人。这就导致m2(收到c1、c3)和m3(收到c2、c3)因为收到了其中某个活动被排除,完全不符合你要保留“未收到全部三个活动”的需求。
第二个查询的问题
- 外层
filter要求收件人至少收到c2/c3/c4中的一个,直接把campaignActivity为空的m1排除了,不符合预期; should条件默认minimum_should_match: 0,意味着即使收件人同时收到了c2、c3、c4(比如nm1),只要满足filter条件就会被返回——因为should可以一个都不满足,这就是nm1不该出现却被返回的原因。
正确的查询方案
你的核心需求是:保留所有收件人,除了那些同时收到c2、c3、c4全部三个活动的人(包括campaignActivity为空的收件人)。
对应的Elasticsearch查询应该这样写:
{ "query": { "bool": { "must_not": [ { "bool": { "must": [ { "nested": { "path": "campaignActivity", "query": { "bool": { "filter": [ {"term": {"campaignActivity.event.keyword": "received"}}, {"term": {"campaignActivity.campaignId.keyword": "c2"}} ] } } } }, { "nested": { "path": "campaignActivity", "query": { "bool": { "filter": [ {"term": {"campaignActivity.event.keyword": "received"}}, {"term": {"campaignActivity.campaignId.keyword": "c3"}} ] } } } }, { "nested": { "path": "campaignActivity", "query": { "bool": { "filter": [ {"term": {"campaignActivity.event.keyword": "received"}}, {"term": {"campaignActivity.campaignId.keyword": "c4"}} ] } } } } ] } } ] } }, "from": 0, "size": 10 }
查询逻辑解释
must_not内部包裹了一个bool.must,这个must里的三个nested查询是**“与”的关系**:只有当一个收件人同时存在c2收到、c3收到、c4收到这三个嵌套活动时,才会被排除;- 对于campaignActivity为空的m1,因为不满足
must_not里的任何条件,会被正常保留; - 对于只收到部分活动的m2(c1、c3)、m3(c2、c3),他们无法同时满足三个
nested条件,所以会被保留; - 而同时收到三个活动的nm1,会被
must_not排除,完全符合你的预期。
内容的提问来源于stack exchange,提问作者Carlos Castellanos
相关产品推荐
相关产品推荐

