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

MongoDB如何更新数组内最大版本对应的字段

问题描述

需求:在数组过滤器中针对最大版本参数更新对应值。

原始文档

{
  _id: '9839021321',
   forms: [
    {
      formName: 'sample_form_name',
      version: [
        {
          version: '1',
          expirationDate: '2025-01-30',
          status: 'Inactive'
        },
        {
          version: '2',
          expirationDate: '2025-03-15',
          status: 'Inactive'
        },
        {
          version: '3',
          expirationDate: '2025-06-23',
          status: 'Inactive'
        }
      ]
    }
  ]
}

期望修改后的文档

{
  _id: '9839021321',
   forms: [
    {
      formName: 'sample_form_name',
      version: [
        {
          version: '1',
          expirationDate: '2025-01-30',
          status: 'Inactive'
        },
        {
          version: '2',
          expirationDate: '2025-03-15',
          status: 'Inactive'
        },
        {
          version: '3',
          status: 'Active'
        }
      ]
    }
  ]
}

已编写的update操作结构

db["flows"].updateMany(
    {"_id":"id_value"},
    {
        "$unset": {"forms.$[f].version.$[v].expirationDate": "true"},
        "$set":   {"forms.$[f].version.$[v].status": "Active"}
        },
    {"arrayFilters":
        [
            {"f.formName":{"$eq":"form_name_value"}},
            {"v.status":  {"$eq": "Active"}},
            {"v.version": { /* 需要只影响版本号最大的元素 */}},
        ]});

问题:如何在arrayFilters中指定匹配最大的v.version?仅了解aggregate用于数据查询,不知道怎么在更新操作里实现。


解决方案

MongoDB的arrayFilters没法直接在更新语句里筛选出数组里的最大值元素,它只支持简单条件匹配,用不了聚合函数计算。要实现这个需求,得改用聚合管道式更新,靠聚合操作定位最大版本再完成修改:

db["flows"].updateMany(
  { "_id": "id_value" },
  [
    {
      $set: {
        forms: {
          $map: {
            input: "$forms",
            as: "f",
            in: {
              $cond: [
                { $eq: ["$$f.formName", "form_name_value"] },
                {
                  ..."$$f",
                  version: {
                    $map: {
                      input: "$$f.version",
                      as: "v",
                      in: {
                        $cond: [
                          { $eq: ["$$v.version", { $max: "$$f.version.version" }] },
                          {
                            version: "$$v.version",
                            status: "Active"
                          },
                          "$$v"
                        ]
                      }
                    }
                  }
                },
                "$$f"
              ]
            }
          }
        }
      }
    }
  ]
)

代码说明:

  • 外层$map遍历forms数组,找出匹配目标formName的表单;
  • 内层$map遍历该表单下的version数组,用$max拿到当前表单里的最大版本号;
  • 通过$cond判断当前版本是不是最大值:
    • 是的话,就把status设为Active,同时自动去掉expirationDate(因为新对象里没这个字段);
    • 不是的话,就保留原版本的所有内容。

要是你想显式用unset而不是靠省略字段来移除,可以把内层的$cond分支改成这样:

{
  $mergeObjects: [
    "$$v",
    { status: "Active", expirationDate: "$$REMOVE" }
  ]
}

这样就能精准定位到每个目标表单里的最大版本,完成状态更新和过期日期的移除。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 20:22:37