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

如何在Mongoose中一次统计同一属性不同值的文档数量

一次查询统计MongoDB中布尔属性的两种状态数量

你可以通过Mongoose的**聚合管道(Aggregation Pipeline)**实现一次查询完成统计,无需两次调用countDocuments。下面提供两种简洁的实现方式:

方法一:分步分组转换格式

// 替换成你的Mongoose模型名
YourModel.aggregate([
  // 第一步:按isCompleted的值分组,统计每组数量
  {
    $group: {
      _id: "$isCompleted",
      count: { $sum: 1 }
    }
  },
  // 第二步:将分组结果合并为目标格式
  {
    $group: {
      _id: null,
      completed: { $sum: { $cond: { if: { $eq: ["$_id", true] }, then: "$count", else: 0 } } },
      notCompleted: { $sum: { $cond: { if: { $eq: ["$_id", false] }, then: "$count", else: 0 } } }
    }
  },
  // 第三步:移除多余的_id字段
  {
    $project: {
      _id: 0
    }
  }
])
.then(result => {
  // 结果示例:{ completed: 4, notCompleted: 6 }
  console.log(result[0]);
})
.catch(err => {
  console.error("统计失败:", err);
});

逻辑说明:

  1. $group(第一步):按isCompleted的布尔值分组,计算每组的文档总数,得到类似[{ _id: true, count:4 }, { _id: false, count:6 }]的中间结果。
  2. $group(第二步):将所有分组数据合并为一个文档,通过$cond条件判断分别累加completed和notCompleted的数量。
  3. $project:移除默认生成的_id字段,得到干净的目标格式。

方法二:用数组转对象简化代码

如果你觉得上面的步骤繁琐,可以用$arrayToObject和$replaceRoot直接生成目标格式:

YourModel.aggregate([
  {
    $group: {
      _id: "$isCompleted",
      count: { $sum: 1 }
    }
  },
  {
    $group: {
      _id: null,
      stats: {
        $push: {
          // 将布尔值映射为对应的键名
          k: { $cond: { if: "$_id", then: "completed", else: "notCompleted" } },
          v: "$count"
        }
      }
    }
  },
  {
    // 将stats数组转换为对象,作为根文档
    $replaceRoot: {
      newRoot: { $arrayToObject: "$stats" }
    }
  }
])
.then(result => {
  console.log(result[0]);
})
.catch(err => {
  console.error("统计失败:", err);
});

处理空状态场景

如果某类状态(比如没有isCompleted: true的文档)不存在,上面的方法会缺失对应的字段。如果需要确保始终返回completed和notCompleted(值为0),可以修改聚合管道:

YourModel.aggregate([
  {
    $group: {
      _id: "$isCompleted",
      count: { $sum: 1 }
    }
  },
  {
    $group: {
      _id: null,
      completed: { $sum: { $cond: { if: { $eq: ["$_id", true] }, then: "$count", else: 0 } } },
      notCompleted: { $sum: { $cond: { if: { $eq: ["$_id", false] }, then: "$count", else: 0 } } }
    }
  },
  {
    $project: {
      _id: 0,
      // 用$ifNull确保字段存在,默认值为0
      completed: { $ifNull: ["$completed", 0] },
      notCompleted: { $ifNull: ["$notCompleted", 0] }
    }
  }
])

内容的提问来源于stack exchange,提问作者Saman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 00:05:10