MongoDB按学生分组统计成绩等级数量的实现方法咨询
解决MongoDB按学生分组统计不同成绩数量的问题
嘿,作为MongoDB新手,刚接触aggregate的时候确实容易搞不清管道阶段的组合逻辑,我来一步步帮你实现想要的统计结果!
你的需求是按学生分组,统计每个学生各等级成绩的数量,针对给定的数据集,我们可以通过**两次$group**配合其他操作来完成,具体的聚合查询代码如下:
db.collection.aggregate([ // 第一步:先按「学生+成绩」的组合分组,统计每个组合的出现次数 { $group: { _id: { student: "$student", grade: "$grade" }, count: { $sum: 1 } } }, // 第二步:按学生重新分组,把每个成绩的统计结果拼成键值对结构的数组 { $group: { _id: "$_id.student", gradeCounts: { $push: { k: "$_id.grade", v: "$count" } } } }, // 可选优化:把数组转成直观的对象,同时重命名字段让输出更清晰 { $project: { _id: 0, student: "$_id", gradeCounts: { $arrayToObject: "$gradeCounts" } } } ])
执行后你会得到这样的结果:
[ { "student": "a", "gradeCounts": { "A": 1, "B": 1 } }, { "student": "B", "gradeCounts": { "C": 2 } } ]
我来拆解下每一步的作用:
- 第一个
$group阶段:我们同时以student和grade作为分组依据,用$sum:1来统计每个「学生+成绩」组合的出现次数。这一步会把原始数据拆分成每个学生对应单个成绩的统计项。 - 第二个
$group阶段:这次只按student分组,用$push把每个成绩的统计项(包含键k和值v)收集到一个数组里。这里的k就是成绩等级,v是对应的数量。 $project阶段:这一步是可选的,用$arrayToObject把数组转成键值对形式的对象,让结果可读性更强,同时把原来的_id重命名为student,让输出结构更贴合你的需求。
如果不需要把统计结果转成对象,也可以省略最后一个$project阶段,这样gradeCounts会是一个包含{ k: "A", v:1 }这类元素的数组,同样能满足统计需求。
内容的提问来源于stack exchange,提问作者A.J
相关产品推荐
相关产品推荐

