如何使用Mongoose从嵌套数组中仅返回匹配条件的对象
MongoDB嵌套数组过滤:仅保留满足条件的
array1元素 原始数据结构
{ "_id": "6339f99ee18b2481a04b4fe8", "userId": "60a8a51cf2229813a45d2238", "array1": [ { "someId1": "6339f99ee18b2481a04b4fe9", "customIndex": 2, "array2": [ { "someId2": "6339f99ee18b2481a04b4fea", "startDate": "2022-10-10T19:56:26.000+00:00", "endDate": "2022-10-12T19:56:26.000+00:00" } ] }, { "someId1": "6345ca40112b743fd8172be0", "customIndex": 4, "array2": [ { "someId2": "6345ca40112b743fd8172be1", "startDate": "2022-10-10T19:56:26.000+00:00", "endDate": "2022-10-27T19:56:26.000+00:00" } ] } ] }
问题说明
你需要从array1中仅保留其嵌套的array2里存在endDate > "2022-10-17"的元素,但之前用的find查询会返回整个文档(包括array1的所有元素),因为find仅判断整个文档是否符合条件,不会自动过滤数组内的元素。
解决方案:使用聚合管道过滤嵌套数组
改用aggregate方法,通过聚合管道实现数组元素的精准过滤:
const result = await Collection.aggregate([ // 第一步:筛选出目标文档,减少后续处理量 { $match: { userId: { $in: userIdList }, "array1.array2.endDate": { $gte: new Date("2022-10-17") } } }, // 第二步:过滤array1,只保留符合条件的元素 { $addFields: { array1: { $filter: { input: "$array1", as: "item", cond: { // 判断当前array1元素的array2中是否存在符合条件的endDate $gt: [ { $size: { $filter: { input: "$$item.array2", as: "subItem", cond: { $gte: ["$$subItem.endDate", new Date("2022-10-17")] } } } }, 0 ] } } } } } ]).exec();
代码逻辑说明
$match阶段:先筛选出包含目标userId且存在符合endDate条件的文档,避免对无关文档做后续处理。$addFields阶段:通过两层$filter实现嵌套数组过滤:- 外层
$filter遍历array1的每个元素 - 内层
$filter检查当前array1元素的array2中是否有满足endDate条件的项,通过$size判断结果数量是否大于0,是则保留该array1元素。
- 外层
预期输出
执行后将得到你需要的结果:
{ "_id": "6339f99ee18b2481a04b4fe8", "userId": "60a8a51cf2229813a45d2238", "array1": [ { "someId1": "6345ca40112b743fd8172be0", "customIndex": 4, "array2": [ { "someId2": "6345ca40112b743fd8172be1", "startDate": "2022-10-10T19:56:26.000+00:00", "endDate": "2022-10-27T19:56:26.000+00:00" } ] } ] }
内容的提问来源于stack exchange,提问作者Beginner
相关产品推荐
相关产品推荐

