如何在Mongoose中统计符合条件的嵌套子文档数量
解决MongoDB子文档条件统计问题
嘿,我来帮你搞定这个统计需求!你原来的代码已经用到了$reduce来累加数量,现在只需要在统计的时候加上筛选条件就行,核心是用$filter先把符合name: "doc1"的documents挑出来,再统计长度。
推荐方案(高效版)
直接修改你原来的聚合管道,在$size外面套一层$filter:
Schema.aggregate([ // 第一步:先筛选出目标用户的文档 { $match: { user: username } }, // 第二步:计算符合条件的子文档数量 { $project: { _id: 1, // 保留用户的_id字段 count: { $reduce: { input: "$exercises", // 遍历每个exercise initialValue: 0, // 初始计数为0 in: { $add: [ "$$value", // 之前累计的数量 // 统计当前exercise中name为doc1的documents数量 { $size: { $filter: { input: "$$this.documents", // 当前exercise的documents数组 cond: { $eq: ["$$this.name", "doc1"] } // 筛选条件:name等于doc1 } } } ] } } } } } ])
代码解释
$match:和你原来的逻辑一致,先定位到目标用户的文档,减少后续处理的数据量。$reduce:遍历exercises数组,逐个处理每个exercise里的documents。$filter:在每个exercise的documents数组中,只保留name等于"doc1"的子文档。$size:统计筛选后的子文档数组长度,再累加到总计数里。- 最后保留
_id字段,输出结果就会和你期望的格式完全匹配:{ "_id": "用户的objectId", "count": 2 }
备选方案(拆分数组版)
如果你觉得$reduce的嵌套有点绕,也可以用$unwind拆分数组后再统计,不过这种方法在数组很大的时候性能会稍差:
Schema.aggregate([ { $match: { user: username } }, { $unwind: "$exercises" }, // 拆分数组,每个exercise变成单独文档 { $unwind: "$exercises.documents" }, // 再拆分documents数组 { $match: { "exercises.documents.name": "doc1" } }, // 筛选符合条件的子文档 { $group: { _id: "$_id", count: { $sum: 1 } } } // 分组统计数量 ])
两种方法都能得到你想要的结果,优先推荐第一种高效的$reduce方案哦!
内容的提问来源于stack exchange,提问作者Quần Trần Văn
相关产品推荐
相关产品推荐

