Elasticsearch查询问题:嵌套对象字段匹配时需排除文档
问题分析与解决方案
你的问题出在嵌套查询的逻辑层级上,咱们一步步拆解清楚:
为什么当前查询不符合预期?
你现在的查询是把must_not放在了nested内部的bool里,这个逻辑的意思是:找到那些存在至少一个rules嵌套文档,且该文档的questionDetailConditionalRules.questionDetailId不包含1的父文档。
回到你的示例文档,里面有两个rules对象:第一个包含questionDetailId=1,第二个不包含。所以这个文档会被匹配到(因为第二个rules满足must_not的条件),自然就被返回了——这和你想要的「只要有任意嵌套对象匹配就排除」完全相反。
正确的查询写法
要实现「只要文档中存在任意一个rules嵌套对象,其questionDetailConditionalRules.questionDetailId包含指定术语,就排除整个文档」的需求,应该把nested查询放在外层bool/must_not中,逻辑转变为:排除所有存在符合条件的嵌套文档的父文档。
具体查询语句如下:
{ "query": { "bool": { "must_not": [ { "nested": { "path": "rules", "query": { "terms": { "rules.questionDetailConditionalRules.questionDetailId": [1] } } } } ] } } }
逻辑解释
这个查询的运作方式是:
- 先用
nested查询定位所有包含questionDetailId=1的rules嵌套文档 - 外层的
must_not会直接排除所有拥有这类嵌套文档的父文档 - 你的示例文档因为存在符合条件的嵌套对象,所以会被正确排除
额外提示
如果你的索引映射里,questionDetailConditionalRules本身也是nested类型(从文档结构看有这个可能),那你需要再嵌套一层nested查询,路径指向rules.questionDetailConditionalRules,比如:
{ "query": { "bool": { "must_not": [ { "nested": { "path": "rules", "query": { "nested": { "path": "rules.questionDetailConditionalRules", "query": { "terms": { "rules.questionDetailConditionalRules.questionDetailId": [1] } } } } } } ] } } }
这一步要根据你的实际索引映射判断,如果questionDetailConditionalRules是普通数组而非nested类型,那第一种写法就足够了。
内容的提问来源于stack exchange,提问作者Eager
相关产品推荐
相关产品推荐

