如何在MongoDB中过滤嵌套对象数组,仅返回指定匹配元素?
如何在MongoDB中仅返回数组中匹配条件的元素?
当然可以实现,直接用find的投影只能返回数组中第一个匹配项,要保留所有匹配的数组元素,推荐用聚合框架来处理,下面是针对你需求的具体方案:
方法一:使用$filter+$project(精确指定保留字段)
先通过$match筛选出包含目标元素的文档,再用$project结合$filter过滤数组,只保留符合条件的项:
db.people.aggregate([ // 先筛选出存在apple的文档,减少计算量 { $match: { "fruit.foodName": "apple" } }, // 投影并过滤数组 { $project: { name: 1, date: 1, fruit: { $filter: { input: "$fruit", as: "item", cond: { $eq: ["$$item.foodName", "apple"] } } } } } ])
方法二:使用$filter+$addFields(自动保留其他字段)
如果文档里还有其他需要保留的字段,不想手动逐个指定,用$addFields直接替换原数组更高效:
db.people.aggregate([ { $match: { "fruit.foodName": "apple" } }, { $addFields: { fruit: { $filter: { input: "$fruit", as: "item", cond: { $eq: ["$$item.foodName", "apple"] } } } } } ])
在MongoDB Compass中操作
打开Compass的聚合标签页:
- 点击「添加阶段」,选择
$match,输入查询条件{ "fruit.foodName": "apple" } - 再添加一个阶段,选择
$addFields或$project,填入对应的过滤逻辑即可
为什么不用find的投影?
find里用{ fruit: { $elemMatch: { foodName: "apple" } } }只能返回数组中第一个匹配的apple元素,无法保留所有符合条件的项,所以聚合是更合适的选择。
内容的提问来源于stack exchange,提问作者Oliver
相关产品推荐
相关产品推荐

