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

MongoDB按员工统计数组内score总分并筛选不合格员工

解决MongoDB按员工统计总分并筛选不合格员工的问题

嗨,我来帮你搞定这个问题!你现在得到所有分数总和的原因很简单——在$group阶段里你写错了分组字段:你用了_id: "$id",但你的文档里员工的ID字段是_id(带下划线的),MongoDB找不到id字段,所以所有文档都被归到了同一个_id: null的分组里,自然算出的是所有分数的总和。

而且其实你完全不需要用$unwind,MongoDB支持直接对数组类型的字段使用$sum,它会自动把数组里的所有数值加起来,这样既简洁又高效。

下面是正确的聚合管道,能帮你按每位员工统计总分,再筛选出不合格的员工:

db.PQRCorp.aggregate([
  // 第一步:按员工分组,计算每位员工的总分,同时保留姓名
  {
    $group: {
      _id: "$_id", // 用文档里的_id字段分组,确保每个员工单独成组
      name: { $first: "$name" }, // 提取该员工的姓名(同一个组里姓名唯一)
      totalTermScore: { $sum: "$results.score" } // 直接对results数组的score字段求和
    }
  },
  // 第二步:筛选出总分不合格的员工,这里假设合格线是20,你可以按需调整
  {
    $match: {
      totalTermScore: { $lt: 20 } // $lt表示小于,换成$lte就是小于等于
    }
  }
])

各阶段说明:

  • $group阶段:

    • _id: "$_id":确保每个员工的文档被分到单独的组里,不会混在一起。你也可以换成_id: "$name",用姓名分组(如果姓名唯一的话),结果会更直观。
    • $first: "$name":因为同一个员工的所有数据(这里其实每个员工只有一条文档)里姓名是相同的,所以用$first就能拿到该员工的姓名。
    • $sum: "$results.score":MongoDB会自动遍历results数组中的每一个对象,把里面的score值全部加起来,得到该员工的总分。
  • $match阶段:
    这里根据你的需求筛选总分不合格的员工,示例里用了$lt: 20表示总分小于20的员工,你可以根据实际的合格阈值修改数值,或者换成其他比较运算符(比如$lte、$gt等)。

如果出于学习目的,你想试试用$unwind的写法(虽然性能不如上面的方法),也可以参考下面的代码:

db.PQRCorp.aggregate([
  { $unwind: "$results" }, // 把results数组拆分成单独的文档
  {
    $group: {
      _id: "$_id", // 正确的分组字段
      name: { $first: "$name" },
      totalTermScore: { $sum: "$results.score" }
    }
  },
  { $match: { totalTermScore: { $lt: 20 } } }
])

这个写法先把每个员工的results数组拆成多条文档,再按员工ID分组求和,最后筛选,结果和第一种方法一样,但处理大量数据时,第一种方法的效率会更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:53:33