Elasticsearch如何筛选所有嵌套assets均匹配指定teamId的根文档
问题分析
你的需求本质是:根文档的assets数组中每一个嵌套对象的teams字段,都要和查询传入的团队ID列表存在交集,才返回根文档。
你之前写的查询逻辑仅校验是否存在至少一个符合条件的assets嵌套对象,所以不符合需求。
正确查询思路
采用反向排除法实现需求:
- 只要不存在「
teams和传入的团队ID列表完全没有交集」的assets嵌套对象,就说明所有assets都满足要求 - 额外兼容
assets为空数组的可选逻辑,如果不需要可以删掉对应的should分支
注意:请确认你的索引mapping中
assets字段类型为nested,否则下述查询不会生效。
完整DSL示例
比如你要查询的团队ID列表为[1,3],查询语句如下:
{ "from": 0, "size": 999, "query": { "bool": { "should": [ // 分支1:assets非空时,所有asset都满足teams和查询列表有交集 { "bool": { "must": [ // 先确认assets存在且非空 { "nested": { "path": "assets", "query": { "exists": { "field": "assets" } } } }, // 核心逻辑:不存在任何一个asset,其teams和查询列表完全无交集 { "bool": { "must_not": [ { "nested": { "path": "assets", "query": { "bool": { "must_not": [ { "terms": { "assets.teams": [1,3] // 这里替换为你要查询的团队ID列表 } } ] } } } } ] } } ] } }, // 分支2:assets为空数组时也返回,不需要可以删除这个分支 { "bool": { "must_not": [ { "nested": { "path": "assets", "query": { "exists": { "field": "assets" } } } } ] } } ], "minimum_should_match": 1 } } }
效果验证
针对你给出的示例文档:
- 传入团队ID为
[1,3]、[1,4]、[1,3,4]时,不存在不符合条件的assets对象,文档正常返回 - 传入团队ID仅为
[1]时,id为101的asset的teams值4、3均不在查询列表中,存在不符合条件的对象,文档不会返回
完全匹配你的需求。
内容的提问来源于stack exchange,提问作者Adam Kaminiecki
相关产品推荐
相关产品推荐

