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

如何用MongoDB聚合操作计算嵌套数组同类型分数的平均值?

MongoDB聚合实现按分数类型计算平均分并重组结构

可以通过以下聚合管道实现需求,核心思路是拆分分数数组、按类型分组计算平均分,再重组回目标结构:

完整聚合命令

db.students.aggregate([
  // 拆分scores数组为单个文档,便于按type分组计算
  { $unwind: "$scores" },
  // 按学生标识和分数类型分组,直接计算平均分
  {
    $group: {
      _id: {
        original_id: "$_id",
        student_id: "$student_id",
        class_id: "$class_id",
        type: "$scores.type"
      },
      avgScore: { $avg: "$scores.score" }
    }
  },
  // 重新按学生分组,将不同类型的平均分组装回scores数组
  {
    $group: {
      _id: "$_id.original_id",
      student_id: { $first: "$_id.student_id" },
      class_id: { $first: "$_id.class_id" },
      scores: {
        $push: {
          type: "$_id.type",
          score: "$avgScore"
        }
      }
    }
  },
  // 可选:格式化分数小数位数,匹配示例结果精度
  {
    $set: {
      scores: {
        $map: {
          input: "$scores",
          as: "item",
          in: {
            type: "$$item.type",
            score: { $round: ["$$item.score", 10] }
          }
        }
      }
    }
  }
])

管道阶段说明

  • $unwind:将每个学生的scores数组拆分为独立文档,每个文档仅包含单个分数条目,为后续分组计算提供基础。
  • $group(第一阶段):以学生原始_id、student_id、class_id和分数type作为分组键,使用$avg直接计算该类型分数的平均值,无需手动计算总和与数量。
  • $group(第二阶段):重新按学生原始_id分组,通过$push将同一学生的不同类型平均分结果组装回scores数组,同时保留student_id和class_id字段。
  • $set(可选):通过$map遍历scores数组,用$round格式化分数的小数位数,确保输出结果与示例精度一致。

最终输出结果

运行上述命令后,将得到与目标结构完全匹配的文档:

{
  _id: ObjectId("50b59cd75bed76f46522c34e"),
  student_id: 0,
  class_id: 2,
  scores: [
    { type: 'exam', score: 57.9294711258 },
    { type: 'quiz', score: 21.2454258821 },
    { type: 'homework', score: 51.6520826017 }
  ]
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 14:37:46