Elasticsearch嵌套查询中must_not不符合预期的问题求助
Elasticsearch嵌套字段排除指定角色查询异常问题
索引数据说明
索引中有4个用户,每个用户包含嵌套类型的roles字段,具体数据如下:
- 用户ID=1的roles:
{ "id": [1] }
- 用户ID=2的roles:
{ "id": [1] }, { "id": [2] }, { "id": [3] }
- 用户ID=3的roles:
{ "id": [2] }, { "id": [3] }
- 用户ID=4的roles:
{ "id": [3] }
即:用户1仅有角色ID=1,用户2拥有角色ID=1、2、3,用户3拥有角色ID=2、3,用户4仅有角色ID=3。
正常的包含查询
使用以下查询可以正确获取所有拥有角色ID=3的用户,返回结果为用户ID=2、3、4:
{ "query": { "bool": { "must": [ { "bool": { "should": [ { "nested": { "path": "roles", "query": { "bool": { "must": [ { "match": { "roles.id": 3 } } ] } } } } ] } } ] } } }
排除查询的异常情况
将上述查询中的must改为must_not后,意图获取所有没有角色ID=3的用户,期望仅返回用户ID=1,但实际返回了用户ID=1、2、3,只有用户4被排除,不符合预期。
问题原因及解决方案
原因
嵌套字段的must_not逻辑是:只要父文档下存在任意一个嵌套文档不满足查询条件,就会保留该父文档。对于用户2、3来说,他们存在不包含角色ID=3的嵌套文档(比如用户2的角色1、2),所以会被错误地保留下来。
正确查询
要实现“完全不包含角色ID=3”的筛选,需要排除所有存在至少一个角色ID=3的嵌套文档的父用户,正确的查询如下:
{ "query": { "bool": { "must_not": [ { "nested": { "path": "roles", "query": { "match": { "roles.id": 3 } } } } ] } } }
这个查询会直接排除所有包含角色ID=3的用户,最终仅返回用户ID=1,符合预期。
内容的提问来源于stack exchange,提问作者fico7489
相关产品推荐
相关产品推荐

