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

MongoDB多级lookup关联查询:如何正确关联用户已报课程、模块及课时数据

MongoDB多集合条件关联查询聚合语句修正

问题根源

原有代码的核心错误出在分组逻辑:

  1. 第一次$group阶段使用用户_id作为分组键,导致同一个用户的所有报名课程被合并到同一分组,$first操作符仅会取第一条课程的基础信息,所有课程的模块被统一推入同一个modules数组,无法按课程拆分
  2. 末尾多余的第二层$group进一步把所有聚合结果合并为1条,彻底丢失多课程结构

修正后的聚合代码

let courseDetails = await users.aggregate([
  {
    $match: { _id: mongoose.Types.ObjectId(user._id) }
  },
  { $unwind: "$enrolled_courses" },
  {
    $lookup: {
      from: 'courses',
      localField: "enrolled_courses.course_id",
      foreignField: "_id",
      as: "courseDetails"
    }
  },
  { $unwind: { path: "$courseDetails", preserveNullAndEmptyArrays: true } },
  {
    $lookup: {
      from: "modules",
      let: { currentCourseId: "$courseDetails._id" },
      pipeline: [
        {
          $match: {
            $expr: {
              $and: [
                { $eq: ["$course_id", "$$currentCourseId"] },
                { $eq: ["$status", 1] },
                { $eq: ["$is_deleted", 0] },
                {
                  $or: [
                    { $eq: ["$is_always_available", true] },
                    { $gte: ["$due_date", convertedDate] }
                  ]
                }
              ]
            }
          }
        },
        {
          $project: {
            _id: 1,
            module_name: 1,
            company_id: 1,
            course_id: 1
          }
        }
      ],
      as: "moduleList"
    }
  },
  { $unwind: { path: "$moduleList", preserveNullAndEmptyArrays: true } },
  {
    $lookup: {
      from: "lessons",
      let: { curentModuleId: "$moduleList._id" },
      pipeline: [
        {
          $match: {
            $expr: {
              $and: [
                { $eq: ["$status", 1] },
                { $eq: ["$is_deleted", 0] },
                { $eq: ["$module_id", "$$curentModuleId"] }
              ]
            }
          }
        },
        {
          $project: {
            _id: 1,
            lessson_name: 1,
            module_id: 1
          }
        }
      ],
      as: "moduleList.lessons"
    }
  },
  // 核心修改:按课程ID分组,而非用户ID
  {
    $group: {
      _id: "$enrolled_courses.course_id",
      course_id: { $first: "$enrolled_courses.course_id" },
      course_name: { $first: "$courseDetails.course" },
      completed_lessons: { $first: "$enrolled_courses.completed_lessons" },
      current_lessons: { $first: "$enrolled_courses.current_lessons" },
      completed: { $first: "$enrolled_courses.completed" },
      enrolled_users_count: { $first: "$courseDetails.enrolled_users" },
      // 仅推入当前课程的模块
      modules: { $push: "$moduleList" }
    }
  },
  {
    $project: {
      _id: 0,
      course_id: 1,
      course_name: 1,
      completed_lessons: 1,
      current_lessons: 1,
      completed: 1,
      enrolled_users_count: { $size: "$enrolled_users_count" },
      // 过滤无有效模块的空值,不需要可以删掉这行
      modules: { $filter: { input: "$modules", cond: { $ne: ["$$this", null] } } }
    }
  }
  // 移除原来末尾多余的第二次group
]);

补充说明

如果需要保留没有符合条件模块的课程,删掉$project阶段中modules字段的$filter过滤逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 21:36:05