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

MongoDB嵌套数组场景下带upsert的update更新操作实现方法

MongoDB会议指标追加Upsert解决方案

前提要求

  • MongoDB版本 ≥ 4.2(支持update操作传入聚合管道)

实现逻辑

通过聚合管道形式的update操作,一次性覆盖「会议不存在新建」「会议存在用户不存在新增用户」「会议用户都存在追加指标到最后一个会话」三类场景,不需要额外事务或多次查询。

具体代码

首先把你要写入的指标数据定义为变量:

// 可替换为你实际要插入的业务数据
const payload = { 
  "conf": "conference12345",
  "uid": "2dd8b4e3-9dcd-4da6-bc36-aa0988dc9642",
  "metrics": {
    "ts": 1234567891,
    "bw":356
  }
}

然后执行带upsert的update操作:

db.collection.update(
  // 匹配条件:按会议ID查询
  { "conf": payload.conf },
  // 聚合管道,分两步处理嵌套数组
  [
    // 第一步:不存在对应用户则先新增用户
    {
      $set: {
        "users": {
          $cond: {
            if: { $not: { $in: [payload.uid, "$users.uid"] } },
            then: { $concatArrays: [ {$ifNull:["$users", []]}, [ { uid: payload.uid, sessions: [] } ] ] },
            else: "$users"
          }
        }
      }
    },
    // 第二步:对目标用户的最后一个会话追加指标
    {
      $set: {
        "users": {
          $map: {
            input: "$users",
            as: "u",
            in: {
              $cond: {
                if: { $eq: ["$$u.uid", payload.uid] },
                then: {
                  uid: "$$u.uid",
                  sessions: {
                    $cond: {
                      // 用户无会话则新建会话存入指标
                      if: { $eq: [{ $size: "$$u.sessions" }, 0] },
                      then: [ [ payload.metrics ] ],
                      // 有会话则追加指标到最后一个会话
                      else: {
                        $concatArrays: [
                          { $slice: ["$$u.sessions", 0, { $subtract: [ { $size: "$$u.sessions" }, 1 ] } ] },
                          [ { $concatArrays: [ { $last: "$$u.sessions" }, [ payload.metrics ] ] } ]
                        ]
                      }
                    }
                  }
                },
                else: "$$u"
              }
            }
          }
        }
      }
    }
  ],
  // 开启upsert,会议不存在时自动创建文档
  { upsert: true }
)

效果验证

  • 新会议新用户场景:传入conf: "conferenceXYZ"的测试数据,执行后会自动创建完整的会议文档,结构和你给出的示例完全一致
  • 已有用户场景:传入conf: "conference12345"的测试数据,执行后对应用户的最后一个会话数组末尾会新增传入的指标项

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 01:42:04