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

如何执行MongoDB lookup并合并多集合关联结果为单一数据集

MongoDB多集合关联按好友维度合并解决方案

你之前尝试用$unionWith不符合需求,这个操作符是用来合并多个集合的同结构文档,不适合做跨集合的维度关联。你遇到的_id和userId字段差异的问题,通过在匹配阶段指定对应字段做等值关联即可解决,完整的聚合查询如下:

db.users.aggregate([
  // 匹配目标用户a
  {
    $match: { _id: "a" }
  },
  // 关联查询a的好友关系列表
  {
    $lookup: {
      from: "friends",
      localField: "_id",
      foreignField: "userId",
      as: "a_myfriends"
    }
  },
  // 关联查询所有好友的邮箱信息
  {
    $lookup: {
      from: "users",
      localField: "a_myfriends.otherUserId",
      foreignField: "_id",
      as: "emailaddr"
    }
  },
  // 关联查询所有好友的发件数量,自动过滤a本人的记录
  {
    $lookup: {
      from: "emailsSent",
      localField: "a_myfriends.otherUserId",
      foreignField: "userId",
      as: "emailsent"
    }
  },
  // 按好友维度合并三个数组的信息
  {
    $project: {
      _id: 1,
      a_myfriends: {
        $map: {
          input: "$a_myfriends",
          as: "friend",
          in: {
            otherUserId: "$$friend.otherUserId",
            email: {
              $getField: {
                input: { $first: { $filter: { input: "$emailaddr", cond: { $eq: ["$$this._id", "$$friend.otherUserId"] } } } },
                field: "email"
              }
            },
            number: {
              $getField: {
                input: { $first: { $filter: { input: "$emailsent", cond: { $eq: ["$$this.userId", "$$friend.otherUserId"] } } } },
                field: "number"
              }
            }
          }
        }
      }
    }
  },
  // 清理无发件记录好友的null字段,匹配预期输出
  {
    $addFields: {
      a_myfriends: {
        $map: {
          input: "$a_myfriends",
          as: "item",
          in: {
            $arrayToObject: {
              $filter: {
                input: { $objectToArray: "$$item" },
                cond: { $ne: ["$$this.v", null] }
              }
            }
          }
        }
      }
    }
  }
])

核心逻辑说明

  • 前4个阶段是你当前已有的查询逻辑,核心改动在后续的数组合并处理阶段
  • 通过$map遍历每一条好友关系,对单个好友分别匹配邮箱数组和发件数数组的对应记录:
    1. 邮箱匹配:用$filter筛选users集合返回的数组中_id等于好友otherUserId的记录,取出邮箱字段
    2. 发件数匹配:用$filter筛选emailsSent集合返回的数组中userId等于好友otherUserId的记录,取出发件数字段
  • 最后清理阶段会自动删除无发件记录的好友的number字段,输出和你要求完全一致的结构

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 07:39:04