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

MongoDB聚合管道按Class属性分组时统计数据异常的排查与优化

问题分析与解决方案

问题原因

  • 重复展开导致统计冗余:你连续对$classes和$classes.students执行$unwind操作,会把每个班级下的每一条学生记录拆分为独立文档。如果同一班级(同一level)下存在多条学生记录,分组统计时会将这些记录的boyz和girls重复累加,最终导致统计值异常重复。
  • 投影字段错误:$project阶段中level: "$_id.classes.level"是错误写法,分组_id中的level直接来自"$classes.level",正确取值应为"$_id.level"。

修正后的聚合管道

场景1:students数组存储班级男女统计值

如果Student文档的boyz和girls是对应班级的整体男女数量,无需展开students数组,直接基于班级维度求和即可:

const pipeline = SchoolModel.aggregate([
  {
    $match: { year: '2021-2022' }
  },
  {
    $unwind: "$classes" // 仅展开班级数组
  },
  {
    $group: {
      _id: {
        stx: "$stx",
        location: "$location",
        level: "$classes.level"
      },
      boyz: {
        $sum: "$classes.students.boyz"
      },
      girls: {
        $sum: "$classes.students.girls"
      }
    }
  },
  {
    $project: {
      _id: 0,
      stx: "$_id.stx",
      location: "$_id.location",
      level: "$_id.level",
      boyz: 1,
      girls: 1
    }
  }
]);

const results = await pipeline.exec();
res.status(200).json(results);

场景2:students数组存储单个学生信息

如果Student文档是单个学生的记录(boyz/girls为性别标识,比如1表示对应性别),则保留$unwind: "$classes.students",但修正投影字段:

const pipeline = SchoolModel.aggregate([
  {
    $match: { year: '2021-2022' }
  },
  {
    $unwind: "$classes"
  },
  {
    $unwind: "$classes.students"
  },
  {
    $group: {
      _id: {
        stx: "$stx",
        location: "$location",
        level: "$classes.level"
      },
      boyz: {
        $sum: "$classes.students.boyz"
      },
      girls: {
        $sum: "$classes.students.girls"
      }
    }
  },
  {
    $project: {
      _id: 0,
      stx: "$_id.stx",
      location: "$_id.location",
      level: "$_id.level",
      boyz: 1,
      girls: 1
    }
  }
]);

const results = await pipeline.exec();
res.status(200).json(results);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 05:27:27