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

MongoDB聚合:对$lookup结果分组并映射到带匹配键的模块对象列表

MongoDB聚合实现方案

你现有$lookup逻辑已经可以正确拉取班级关联的所有作业,后续只需要遍历模块数组、匹配对应作业挂载即可,不需要额外做分组操作,完整聚合管道如下:

const lookupPipeline = [
  // 原有$lookup关联阶段,保留即可
  {
    $lookup: {
      from: "assignments",
      localField: "modules.id",
      foreignField: "moduleId",
      as: "assignments"
    }
  },
  // 重写modules数组,为每个模块挂载对应作业
  {
    $addFields: {
      modules: {
        $map: {
          input: "$modules",
          as: "module",
          in: {
            $mergeObjects: [
              // 保留模块原有全部字段
              "$$module",
              {
                // 过滤匹配当前模块ID的作业
                assignments: {
                  $filter: {
                    input: "$assignments",
                    cond: { $eq: ["$$this.moduleId", "$$module.id"] }
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  // 可选:移除顶层临时生成的assignments字段,和期望输出结构完全对齐
  {
    $project: {
      assignments: 0
    }
  }
]
逻辑说明
  • 第一阶段$lookup会将当前班级所有模块关联的作业全部查询到,挂载在文档顶层的assignments数组中
  • 第二阶段通过$addFields重写modules字段:用$map遍历原有模块数组的每一项,通过$mergeObjects保留模块原有属性,同时新增assignments字段;该字段的值通过$filter从顶层作业列表中筛选moduleId与当前模块ID一致的条目,无匹配作业的模块会自动得到空数组,完全符合预期结构
  • 最后一个$project阶段为可选配置,如果不需要保留顶层临时拉取的作业列表就添加,需要保留可以直接删除该阶段

注意:如果modules.id和assignments.moduleId的字段类型不一致(例如一个是ObjectId类型、一个是字符串类型),需要在$eq判断前通过$toString/$toObjectId做类型转换,否则会出现匹配失败的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 23:48:52