Elasticsearch嵌套对象指定条件过滤查询方案咨询
问题根因
你之前查询结果不符合预期,核心是对nested查询的匹配逻辑理解有偏差:
- nested查询的默认匹配规则是:只要父文档下存在任意一个嵌套子文档符合内部查询条件,父文档就会被命中
- 你之前把
nested查询整体放在must_not下,逻辑等价于「排除所有存在任意一个dept-id为1的子文档的父文档」,所以同时关联了dept-1和其他部门的item-1会被直接过滤,仅返回完全没关联dept-1的item-3。
无新增字段的查询方案
你的实际需求是:排除所有关联部门全部属于非活跃列表的文档,保留至少有一个关联部门不在非活跃列表的文档。直接把判断逻辑下沉到nested查询内部即可,不需要加额外字段,可直接运行的DSL如下:
GET items/_search { "query": { "bool": { "must": [ { "nested": { "path": "departments", "query": { "bool": { "must_not": [ { "terms": { "departments.dept-id": ["1"] } } ] } } } } ] } } }
查询逻辑说明
- 外层
must嵌套nested查询的含义是:要求父文档下至少存在一个departments子文档满足内部查询条件 - 内部
must_not+terms的含义是:该子文档的dept-id不属于非活跃部门列表["1"] - 匹配结果:
- item-1存在dept-2、dept-3两个符合条件的子文档,命中
- item-2所有子文档的dept-id都是1,无符合条件的子文档,被过滤
- item-3存在dept-2符合条件的子文档,命中
完全符合预期返回结果。
优化提示
当前dept-id是text类型,如果存储的是部门ID这类不需要分词的精确值,建议后续把dept-id调整为keyword类型,或者使用departments.dept-id.keyword字段做terms匹配,避免分词导致的匹配误差。
内容的提问来源于stack exchange,提问作者Duke
相关产品推荐
相关产品推荐

