MongoDB聚合查询:连接三集合获取嵌套输出遇lookup关联难题
MongoDB 三集合聚合关联解决方案
针对你需要关联department、electives、students三个集合并按部门过滤的需求,以下是完整的聚合查询代码,同时拆解关键步骤解决你在electives与students关联环节的问题:
完整聚合查询
db.department.aggregate([ // 按部门过滤(可替换为你需要的过滤条件) { $match: { departmentName: "Computer Science" } }, // 关联electives集合,获取当前部门的所有选修课 { $lookup: { from: "electives", localField: "_id", foreignField: "departmentId", as: "electivesList" } }, // 拆解electivesList数组,为每个选修课单独关联学生 { $unwind: { path: "$electivesList", preserveNullAndEmptyArrays: true // 保留无选修课的部门 } }, // 关联students集合,获取当前选修课的所有学生 { $lookup: { from: "students", localField: "electivesList._id", foreignField: "electiveId", as: "electivesList.studentsList" } }, // 计算每个选修课的学生数量,映射electiveId字段 { $addFields: { "electivesList.studentsCount": { $size: "$electivesList.studentsList" }, "electivesList.electiveId": "$electivesList._id" } }, // 重新按部门分组,重组electivesList数组 { $group: { _id: "$_id", departmentName: { $first: "$departmentName" }, headOfDepartment: { $first: "$headOfDepartment" }, electivesList: { $push: "$electivesList" } } }, // 调整输出字段,格式化学生列表结构 { $project: { _id: 0, departmentName: 1, headOfDepartment: 1, electivesList: { electiveId: 1, electiveName: 1, studentsCount: 1, studentsList: { $map: { input: "$studentsList", as: "student", in: { studentId: "$$student._id", studentName: "$$student.studentName" } } } } } } ])
关键环节说明
1. 解决electives与students的关联问题
第一次$lookup获取electivesList后,必须通过$unwind拆解数组,让每个选修课条目单独与students集合匹配。直接在嵌套数组上执行$lookup无法正确关联每个选修课对应的学生。
2. 学生数量计算与字段映射
- 用
$size函数直接获取studentsList的长度,得到studentsCount。 - 通过
$addFields将选修课的_id映射为输出要求的electiveId字段。
3. 重组数组与格式化输出
关联完成后,通过$group重新按部门聚合,将拆解后的选修课条目重组为electivesList数组。最后用$project和$map格式化学生列表,只保留需要的studentId和studentName字段。
内容的提问来源于stack exchange,提问作者Gautam Ramasamy
相关产品推荐
相关产品推荐

