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

MongoDB中更新timeds数组:合并同timed值的total并新增元素

MongoDB 更新timeds数组:累加或新增元素方案

示例文档结构

假设你的视频访客数据文档结构如下:

{
  "_id": ObjectId("60d21b4667d0d8992e610c85"),
  "videoId": "demo-video-001",
  "timeds": [
    {"timed": 10, "total": 5},
    {"timed": 20, "total": 3}
  ]
}

需求是:添加新的{timed: x, total: y}元素时,若x已在timeds的timed字段中存在,则累加对应total;若不存在,则直接新增该元素到数组。


方案一:分两步原子操作(适合简单场景)

先尝试匹配已有timed的文档并累加,若未匹配到则执行新增:

// 定义要添加的新数据
const newTimedEntry = { timed: 20, total: 2 };
const targetDocId = ObjectId("60d21b4667d0d8992e610c85"); // 目标文档ID

// 第一步:尝试累加已有timed对应的total
const updateResult = await db.collection('video_visitors').updateOne(
  { _id: targetDocId, "timeds.timed": newTimedEntry.timed },
  { $inc: { "timeds.$.total": newTimedEntry.total } }
);

// 若没有匹配到文档,说明timed不存在,执行新增
if (updateResult.matchedCount === 0) {
  await db.collection('video_visitors').updateOne(
    { _id: targetDocId },
    { $push: { timeds: newTimedEntry } }
  );
}

关键说明

  • "timeds.timed": newTimedEntry.timed:精准定位数组中包含目标timed的文档
  • $:位置操作符,指向数组中匹配到的第一个元素
  • $inc:原子性累加数值,避免并发更新问题

方案二:聚合管道原子更新(MongoDB 4.2+,适合高并发场景)

通过聚合管道一次完成判断、累加或新增操作,全程原子性,避免分两步操作的并发风险:

const newTimedEntry = { timed: 30, total: 4 };
const targetDocId = ObjectId("60d21b4667d0d8992e610c85");

await db.collection('video_visitors').updateOne(
  { _id: targetDocId },
  [
    {
      $set: {
        timeds: {
          $cond: [
            // 判断目标timed是否已存在于数组中
            { $in: [newTimedEntry.timed, "$timeds.timed"] },
            // 存在则遍历数组,匹配元素累加total,其余保留原数据
            {
              $map: {
                input: "$timeds",
                as: "item",
                in: {
                  $cond: [
                    { $eq: ["$$item.timed", newTimedEntry.timed] },
                    { timed: "$$item.timed", total: { $add: ["$$item.total", newTimedEntry.total] } },
                    "$$item"
                  ]
                }
              }
            },
            // 不存在则将新元素追加到数组末尾
            { $concatArrays: ["$timeds", [newTimedEntry]] }
          ]
        }
      }
    }
  ]
);

性能优化建议

如果数据量较大,为timeds.timed字段创建索引可以大幅提升匹配效率:

db.collection('video_visitors').createIndex({"timeds.timed": 1});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 16:35:25