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

MongoDB聚合查询优化:过滤Student文档匹配自身_id的考勤统计

解决Mongoose聚合查询中仅保留当前学生考勤统计的问题

你的问题出在聚合查询的$lookup阶段没有针对当前学生过滤关联数据,导致每个学生文档的counts数组包含了所有学生的考勤统计。下面提供两种高效的解决方法:

方法一:关联阶段直接过滤(性能更优)

在$lookup的内部pipeline中,直接匹配当前学生的_id,只拉取该学生的考勤数据后再统计,避免无关数据的传输和处理:

Student.aggregate([
  // 筛选指定班级的学生
  { $match: { classID: "目标班级ID" } },
  {
    $lookup: {
      from: "attendances",
      let: { currentStudentId: "$_id" },
      pipeline: [
        // 同时匹配目标科目和当前学生ID
        {
          $match: {
            $expr: { $eq: ["$studentID", "$$currentStudentId"] },
            subjectID: "目标科目ID"
          }
        },
        // 统计当前学生的考勤次数
        { $group: { _id: "$studentID", attendanceCount: { $sum: 1 } } }
      ],
      as: "attendanceStats"
    }
  },
  // 将数组转为单个统计对象(可选,根据需求调整)
  { $addFields: { attendanceStats: { $arrayElemAt: ["$attendanceStats", 0] } } }
])

方法二:关联后过滤数据

如果需要保留其他关联场景的灵活性,可以先拉取所有学生的考勤统计,再用$filter筛选出当前学生的项:

Student.aggregate([
  { $match: { classID: "目标班级ID" } },
  {
    $lookup: {
      from: "attendances",
      pipeline: [
        { $match: { subjectID: "目标科目ID" } },
        { $group: { _id: "$studentID", attendanceCount: { $sum: 1 } } }
      ],
      as: "allAttendanceStats"
    }
  },
  // 过滤出当前学生的统计数据
  {
    $addFields: {
      attendanceStats: {
        $filter: {
          input: "$allAttendanceStats",
          cond: { $eq: ["$$this._id", "$_id"] }
        }
      }
    }
  },
  // 移除临时数组(可选)
  { $unset: "allAttendanceStats" },
  // 转为单个对象(可选)
  { $addFields: { attendanceStats: { $arrayElemAt: ["$attendanceStats", 0] } } }
])

效果说明

修改后,每个Student文档的attendanceStats字段(可自定义名称)只会包含当前学生的考勤统计数据:

  • 如果保留数组格式,会是仅含自身统计项的数组
  • 如果使用$arrayElemAt,会直接转为单个统计对象(更符合常规需求)

内容的提问来源于stack exchange,提问作者ommy rock

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 19:10:53