MongoDB非聚合场景下elemMatch筛选数组指定元素的问题
非聚合方式过滤MongoDB嵌套数组元素,保留指定tag项
原始数据
[ { "url": "a", "nested_object_keys": [ { "vendor": "terraform", "tag": "some_tag_1" }, { "vendor": "terraform", "tag": "some_tag_2" }, { "vendor": "terraform", "tag": "some_tag_3" }, { "vendor": "terraform", "tag": "some_tag_4" } ] } ]
期望结果
[ { "url": "a", "nested_object_keys": [ { "vendor": "terraform", "tag": "some_tag_1" }, { "vendor": "terraform", "tag": "some_tag_2" } ] } ]
问题分析
使用$elemMatch配合$in/$or等运算符时,要么返回整个未过滤的数组,要么仅返回第一个匹配的数组元素,无法保留所有符合条件的项。
解决方案(无需聚合管道)
利用MongoDB 4.4及以上版本支持的投影聚合表达式,在find查询中通过$filter筛选数组元素:
db.collection.find( // 可选:先过滤出包含目标tag的文档,减少不必要的处理 { "nested_object_keys.tag": { $in: ["some_tag_1", "some_tag_2"] } }, { "url": 1, "nested_object_keys": { "$filter": { "input": "$nested_object_keys", "as": "item", "cond": { "$in": ["$$item.tag", ["some_tag_1", "some_tag_2"]] } } } } )
说明
- 查询条件:
"nested_object_keys.tag": { $in: [...] }用于筛选出至少包含一个目标tag的文档,避免处理完全不符合要求的文档。 - 投影逻辑:
$filter遍历nested_object_keys数组,对每个元素(别名item)判断其tag是否在指定列表中,仅保留符合条件的元素。 - 该方法属于
find查询的投影操作,未使用聚合管道,满足你的限制条件。
如果你的MongoDB版本低于4.4,无法在投影中使用聚合表达式,此时若严格禁止聚合操作则没有完美解决方案,建议升级版本或使用聚合管道(如$project+$filter)。
内容的提问来源于stack exchange,提问作者Rambo
相关产品推荐
相关产品推荐

