You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 10:30:59