You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 21:37:44