如何编写MongoDB聚合查询获取学生最高分对应科目?
正确的MongoDB聚合查询语句
你的原查询存在两个关键问题:
- 错误引用了不存在的字段
$results,实际集合中存储成绩的字段是marks; - 原数据的
marks是包含科目-分数键值对的对象,而非带有score字段的数组,因此$max: ["$results.score"]的用法不适用。
以下是符合需求的聚合查询:
db.Student3.aggregate([ // 可选:如果只需要特定学生的数据,添加此筛选阶段 { $match: { name: { $in: ["Pawan", "Kartik"] } } }, // 展开marks数组(每个学生的marks数组仅含一个对象) { $unwind: "$marks" }, // 将科目-分数对象转换为键值对数组,便于遍历处理 { $addFields: { subjectScores: { $objectToArray: "$marks" } } }, // 遍历数组找出分数最高的科目 { $addFields: { highestSubject: { $reduce: { input: "$subjectScores", initialValue: { k: "", v: 0 }, in: { $cond: [ { $gt: ["$$this.v", "$$value.v"] }, "$$this", "$$value" ] } } } } }, // 投影输出指定字段,匹配期望的表头 { $project: { _id: 0, "Student Name": "$name", "Name of Subject of Highest Marks": "$highestSubject.k" } } ])
查询步骤说明
- $match(可选):筛选出需要统计的学生,比如你期望输出中的Pawan和Kartik;
- $unwind:展开每个学生的
marks数组,将数组内的科目-分数对象单独提取出来; - $objectToArray:把
marks对象转换为[{k: "科目名称", v: 分数}]格式的数组,让我们可以用数组操作符处理每个科目; - $reduce:遍历科目分数数组,逐个比较分数值,保留分数最高的那个科目键值对;
- $project:重命名字段并输出最终需要的内容,隐藏不需要的
_id等字段。
注:根据你提供的原始数据,Pawan的最高分为Sci(98分),Kartik的最高分为Hindi(80分),与你期望表格中的数据存在差异,若需调整可修改筛选或比较逻辑。
内容的提问来源于stack exchange,提问作者Komati Joshna
相关产品推荐
相关产品推荐

