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

Mongoose如何将$lookup关联数据合并到数组嵌套的对象中

你第二种写法已经接近正确,只需要调整$map的输出逻辑,不要直接合并$zip得到的两个元素,而是把对应用户信息嵌套到user字段中即可,修改后代码如下:

Form.aggregate([
  {
    $lookup: {
      from: 'users',
      localField: 'approvalLog.by',
      foreignField: '_id',
      as: 'approvedBy',
    },
  },
  {
    $addFields: {
      approvalLog: {
        $map: {
          input: { $zip: { inputs: ['$approvalLog', '$approvedBy'] } },
          in: {
            $mergeObjects: [
              { $arrayElemAt: ['$$this', 0] }, // 取原审批日志条目
              { user: { $arrayElemAt: ['$$this', 1] } } // 新增user字段存储对应用户信息
            ]
          },
        },
      },
    },
  },
  // 可选:不需要保留approvedBy字段可开启下面这步移除
  { $unset: 'approvedBy' }
])

如果担心approvalLog和approvedBy的数组顺序不一致导致匹配错误,可以用更稳妥的$unwind拆分后关联再重组的方案:

Form.aggregate([
  // 拆分approvalLog数组为单独的文档
  { $unwind: '$approvalLog' },
  // 关联对应用户
  {
    $lookup: {
      from: 'users',
      localField: 'approvalLog.by',
      foreignField: '_id',
      as: 'approvalLog.user'
    }
  },
  // lookup默认返回数组,把user字段从数组转成单个对象
  { $addFields: { 'approvalLog.user': { $arrayElemAt: ['$approvalLog.user', 0] } } },
  // 按表单_id分组,把拆分的审批日志重新拼回数组,同时保留表单其他字段
  {
    $group: {
      _id: '$_id',
      userId: { $first: '$userId' },
      // 其余表单字段都可以用$first取第一个值保留
      approvalLog: { $push: '$approvalLog' }
    }
  }
])

你第一种写法报错的原因是直接取approvedBy数组的第一个元素赋值给所有审批日志的user字段,自然所有条目都会显示同一个用户。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 17:06:00