如何在MongoDB中按学生ID分组聚合课程成绩数据
模型与数据说明
Marks模型结构包含以下字段:
- courseCode:字符串类型,课程代码
- courseTitle:字符串类型,课程名称
- studentsMarks:数组类型,存储学生ID与对应课程成绩的对象集合
marks集合的示例数据如下:
[ { "_id": "634 ...", "courseCode": "cse1201", "courseTitle": "Structured Programming ", "studentsMarks": [ { "id": "ce17001", "marks": 52, "_id": "634a9be567a1f07b ... " }, { "id": "ce17002", "marks": 50, "_id": "634a9be567a1f07be ... " } ], "type": "theory" }, { "_id": "634a9be567a1f07be0 ...", "courseCode": "cse1202", "courseTitle": "Data Structer", "studentsMarks": [ { "id": "ce17001", "marks": 45, "_id": "634 ..." }, { "id": "ce17002", "marks": 61, "_id": "634 ... " } ], "type": "theory" } ]
需求描述
按学生唯一ID(如ce17001、ce17002)对成绩进行分组,每个学生对应一个成绩数组,数组中包含其所有已修课程的成绩详情(课程代码、课程名称、成绩)。
期望输出
[ { "id": "ce17001", "marksArray": [ { "courseCode": "cse1201", "courseTitle": "Structured Programming", "marks": 52 }, { "courseCode": "cse1202", "courseTitle": "Data structer", "marks": 45 } ] }, { "id": "ce17002", "marksArray": [ { "courseCode": "cse1201", "courseTitle": "Structured Programming", "marks": 50 }, { "courseCode": "cse1202", "courseTitle": "Data structer", "marks": 61 } ] } ]
实现方案
使用MongoDB聚合管道可以直接完成该转换,具体步骤如下:
聚合查询代码
db.marks.aggregate([ // 拆分studentsMarks数组,将每个学生成绩转为独立文档 { $unwind: "$studentsMarks" }, // 按学生ID分组,收集该学生的所有课程成绩信息 { $group: { _id: "$studentsMarks.id", marksArray: { $push: { courseCode: "$courseCode", courseTitle: "$courseTitle", marks: "$studentsMarks.marks" } } } }, // 调整输出结构,移除默认_id并将分组ID重命名为id { $project: { _id: 0, id: "$_id", marksArray: 1 } } ])
代码解释
$unwind:将每个课程文档中的studentsMarks数组展开,每个学生的成绩记录成为单独的文档,同时保留课程的courseCode和courseTitle信息。$group:以学生ID作为分组键,通过$push操作将该学生的所有课程成绩详情(课程代码、名称、成绩)添加到marksArray数组中。$project:调整输出字段,隐藏默认的_id字段,将分组用的_id重命名为id,最终输出符合期望的结构。
内容的提问来源于stack exchange,提问作者Shakhawat Hossain SHIHAB
相关产品推荐
相关产品推荐

