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
相关产品推荐
相关产品推荐

