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

如何在MongoDB中聚合含多维数组的两个关联集合?

MongoDB多维数组跨集合聚合实现方案

针对你需要在嵌套双层数组的集合中关联另一个集合数据的需求,直接用聚合管道即可完成,无需查询后二次处理,具体步骤和完整代码如下:

核心思路

通过逐层展开数组 -> 跨集合关联 -> 逐层重组数组结构的流程,保留原文档的嵌套数组层级,同时注入关联数据。

具体聚合步骤

  1. 展开外层trips数组
    用$unwind将trips数组拆分为单个文档,方便后续处理内部的details数组:

    { $unwind: "$trips" }
    
  2. 展开内层details数组
    继续用$unwind拆分trips.details数组,让每个detail对象成为独立可操作单元:

    { $unwind: "$trips.details" }
    
  3. 关联第二个集合
    用$lookup根据trips.details.key匹配第二个集合的_id,将关联数据存入临时字段:

    {
      $lookup: {
        from: "collection2", // 替换为你的第二个集合名称
        localField: "trips.details.key",
        foreignField: "_id",
        as: "description_temp"
      }
    }
    
  4. 整合关联数据到detail对象
    $lookup返回的是数组,用$addFields取出数组第一个元素(一对一匹配场景),添加为_description_obj字段到trips.details下,并删除临时字段:

    {
      $addFields: {
        "trips.details._description_obj": { $arrayElemAt: ["$description_temp", 0] },
        description_temp: "$$REMOVE"
      }
    }
    
  5. 重组details数组
    用$group按原文档_id和trips的唯一标识分组,将拆分后的detail对象重新推入details数组:

    {
      $group: {
        _id: {
          docId: "$_id",
          tripUniqueKey: "$trips._id" // 若trips无唯一_id,可替换为其他唯一标识或哈希值
        },
        tripsBase: { $first: "$trips" },
        details: { $push: "$trips.details" }
      }
    }
    
  6. 重组trips数组
    再次用$group按原文档_id分组,将重组后的trip对象推入trips数组:

    {
      $group: {
        _id: "$_id.docId",
        trips: {
          $push: {
            // 复制trips原有的非details字段,比如name、date等
            details: "$details"
          }
        }
      }
    }
    
  7. (可选)调整最终字段结构
    用$project明确指定输出字段,确保和原文档结构一致:

    { $project: { _id: 1, trips: 1 } }
    

完整聚合管道代码

替换集合名称和额外字段后,完整代码如下:

db.collection1.aggregate([
  { $unwind: "$trips" },
  { $unwind: "$trips.details" },
  {
    $lookup: {
      from: "collection2",
      localField: "trips.details.key",
      foreignField: "_id",
      as: "description_temp"
    }
  },
  {
    $addFields: {
      "trips.details._description_obj": { $arrayElemAt: ["$description_temp", 0] },
      description_temp: "$$REMOVE"
    }
  },
  {
    $group: {
      _id: {
        docId: "$_id",
        tripUniqueKey: "$trips._id"
      },
      tripsBase: { $first: "$trips" },
      details: { $push: "$trips.details" }
    }
  },
  {
    $group: {
      _id: "$_id.docId",
      trips: {
        $push: {
          details: "$details"
          // 这里添加trips原有的其他字段,如name: "$tripsBase.name"
        }
      }
    }
  },
  { $project: { _id: 1, trips: 1 } }
])

注意事项

  • 若trips无唯一标识,分组时需用哈希或组合字段生成唯一键,避免不同trip的details被错误合并。
  • 若collection2存在多匹配文档,直接赋值"$description_temp"即可保留全部关联数据,无需$arrayElemAt。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 17:40:31