如何使用MongoDB Aggregate提取嵌套文档中的指定考勤数据
解决方案:嵌套数组的多层精准筛选
没问题,你可以通过MongoDB聚合管道中的$map和$filter组合来实现这个需求——因为你需要处理两层嵌套数组(外层的sections和内层的attendance),既要筛选目标班级,又要保留指定学生的考勤记录,同时维持原有的文档结构。
完整的聚合查询语句
db.attendances.aggregate([ { $project: { faculty: 1, sections: { // 第一步:先筛选出目标班级的sections元素 $map: { input: { $filter: { input: "$sections", as: "s", cond: { $eq: ["$$s.section", "DEET 3-1"] } } }, as: "filteredSection", // 第二步:对每个筛选后的班级,再过滤指定学生的考勤记录 in: { section: "$$filteredSection.section", date: "$$filteredSection.date", subject: "$$filteredSection.subject", attendance: { $filter: { input: "$$filteredSection.attendance", as: "a", cond: { $eq: ["$$a.number", "2019-00005-MN-0"] } } } } } } } }, // 可选:过滤掉没有匹配到目标班级的文档(避免返回空sections数组) { $match: { sections: { $ne: [] } } } ])
代码逻辑拆解
- 外层
$filter:先从sections数组中筛选出section为DEET 3-1的元素,缩小后续处理的范围; $map遍历重构:对筛选后的每个班级元素,重新构造其结构——保留section、date、subject等基础字段,同时对嵌套的attendance数组做二次筛选;- 内层
$filter:在每个班级的attendance数组中,只保留number等于2019-00005-MN-0的考勤记录; - 可选
$match:如果集合中存在没有匹配到目标班级的文档,这一步会把它们排除掉,避免返回无用的空结构。
执行这个查询后,就能得到你想要的输出结果:每个文档只保留指定学生的考勤记录,其余结构完全符合你的要求。
内容的提问来源于stack exchange,提问作者NOZU
相关产品推荐
相关产品推荐

