MongoDB聚合查询优化:仅匹配学生ID的出勤统计
问题解决:聚合查询中仅保留当前学生的出勤统计
你的问题核心是$lookup阶段未关联学生自身的_id,导致所有学生都拿到了全量的出勤统计数据。以下是两种直接的修正方案:
方法一:在$lookup管道内关联学生ID
通过let定义当前学生的_id变量,在$match中用$expr匹配出勤记录里的对应学生ID,从源头过滤数据:
await StudentSchema.aggregate([ { $match: { classID: mongoose.Types.ObjectId(`${req.params.id}`), }, }, { $project: { createdAt: 0, updatedAt: 0, __v: 0, password: 0 }, }, { $lookup: { from: "attendances", let: { studentId: "$_id" }, pipeline: [ { $match: { subjectID: mongoose.Types.ObjectId(`${req.params.Sid}`), $expr: { $in: ["$$studentId", "$studentID"] } }, }, { $unwind: "$studentID" }, { $match: { $expr: { $eq: ["$studentID", "$$studentId"] } } }, { $group: { _id: "$studentID", count: { $sum: 1 } } }, ], as: "present", }, }, ]);
方法二:$lookup后过滤present数组
如果不想修改lookup管道,可在查询末尾添加$addFields阶段,用$filter筛选出当前学生的出勤记录:
await StudentSchema.aggregate([ { $match: { classID: mongoose.Types.ObjectId(`${req.params.id}`), }, }, { $project: { createdAt: 0, updatedAt: 0, __v: 0, password: 0 }, }, { $lookup: { from: "attendances", pipeline: [ { $match: { subjectID: mongoose.Types.ObjectId(`${req.params.Sid}`), }, }, { $unwind: "$studentID" }, { $group: { _id: "$studentID", count: { $sum: 1 } } }, ], as: "present", }, }, { $addFields: { present: { $filter: { input: "$present", cond: { $eq: ["$$this._id", "$_id"] } } } } } ]);
两种方案都能让每个学生的present数组仅展示自身的出勤统计,完全匹配你期望的输出格式。
内容的提问来源于stack exchange,提问作者Om Adde
相关产品推荐
相关产品推荐

