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

如何在MongoDB中实现多字段分组并计算平均值?

MongoDB聚合查询:按学生和科目计算平均分

我来帮你搞定这个需求!根据你提供的样本数据和期望输出,我们可以通过MongoDB的聚合框架完成按name和sub分组计算平均分,并整理成目标结构的操作。

完整聚合查询代码

db.student.aggregate([
  // 第一阶段:按学生姓名+科目分组,计算每门科目的平均分
  {
    $group: {
      _id: { name: "$name", sub: "$sub" },
      avgMarks: { $avg: "$marks" }
    }
  },
  // 第二阶段:按学生姓名分组,将该学生的所有科目平均分整理为数组
  {
    $group: {
      _id: "$_id.name",
      subjects: {
        $push: { sub: "$_id.sub", avgMarks: "$avgMarks" }
      }
    }
  },
  // 可选:调整输出字段(这里保持默认即可,若需重命名可修改)
  {
    $project: {
      _id: 1,
      subjects: 1
    }
  }
])

各阶段详细说明

  • 第一个$group阶段:
    我们以name(学生姓名)和sub(科目)的组合作为分组键,用$avg运算符直接计算该分组下的平均分。这一步会生成每个学生每门科目的单独平均分记录。

  • 第二个$group阶段:
    以学生姓名作为分组键,通过$push运算符把同一学生的所有科目平均分数据合并到一个数组里。这一步把分散的科目记录聚合为每个学生的统一条目。

  • $project阶段:
    可选的格式调整阶段,这里我们保留_id(学生姓名)和subjects(科目平均分数组),确保输出结构简洁清晰,符合MongoDB的BSON文档规范。

查询结果示例

运行上述查询后,你会得到如下结果(和你期望的输出几乎一致,仅多了合法的数组键名subjects——因为MongoDB要求所有顶层元素都是键值对,不能直接放置无键名数组):

[
  {
    "_id": "Vikash",
    "subjects": [
      { "sub": "Physics", "avgMarks": 15 },
      { "sub": "Math", "avgMarks": 25 }
    ]
  },
  {
    "_id": "Raj",
    "subjects": [
      { "sub": "Physics", "avgMarks": 22.5 },
      { "sub": "Math", "avgMarks": 15 }
    ]
  }
]

如果需要在客户端进一步调整为你期望的无键名数组格式,可以在获取数据后做简单处理(比如提取subjects数组作为顶层元素,但注意这不符合JSON/BSON规范,仅适合特定展示场景)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 09:42:34