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

MongoDB单更新查询清理嵌套数组:移除缺失指定字段的对象

MongoDB 深层嵌套数组清理的单更新查询方案

需求:通过单个更新查询,移除_a._p.s.[a|c|d].t中缺失did、dst和den字段的对象,同时保证不存在_a._p.s的_a._p对象内容不受破坏。

现有方案缺陷:

  • 某方案在不存在_a._p.s时,会破坏_a._p的原有内容
  • 另一方案在_a._p.s下缺失a/c/d对象时,会自动添加null值对象,不符合预期

原始示例文档

[
  {
    "_id": ObjectId("5c05984246a0201286d4b57a"),
    "f": "x",
    "_a": [
      { "_onlineStore": {} },
      {
        "_p": {
          "s": {
            "a": {
              "t": [
                {
                  "id": 1,
                  "dateP": "20200-09-20",
                  "did": "x",
                  "dst": "y",
                  "den": "z"
                },
                {
                  "id": 2,
                  "dateP": "20200-09-20"
                }
              ]
            },
            "c": {
              "t": [
                { "id": 3, "dateP": "20300-09-22" },
                {
                  "id": 4,
                  "dateP": "20300-09-23",
                  "did": "x",
                  "dst": "y",
                  "den": "z"
                },
                { "id": 5, "dateP": "20300-09-23" }
              ]
            }
          }
        }
      }
    ]
  },
  {
    "_id": ObjectId("5c05984246a0201286d4b57b"),
    "f": "x",
    "_a": [
      { "_onlineStore": {} },
      {
        "_p": {
          "_t": "Some field",
          "_x": "Some other field"
        }
      }
    ]
  }
]

更新后预期结果

[
  {
    "_id": ObjectId("5c05984246a0201286d4b57a"),
    "f": "x",
    "_a": [
      { "_onlineStore": {} },
      {
        "_p": {
          "s": {
            "a": {
              "t": [
                {
                  "id": 1,
                  "dateP": "20200-09-20",
                  "did": "x",
                  "dst": "y",
                  "den": "z"
                }
              ]
            },
            "c": {
              "t": [
                {
                  "id": 4,
                  "dateP": "20300-09-23",
                  "did": "x",
                  "dst": "y",
                  "den": "z"
                }
              ]
            }
          }
        }
      }
    ]
  },
  {
    "_id": ObjectId("5c05984246a0201286d4b57b"),
    "f": "x",
    "_a": [
      { "_onlineStore": {} },
      {
        "_p": {
          "_t": "Some field",
          "_x": "Some other field"
        }
      }
    ]
  }
]

解决方案:单更新查询

db.collection.updateMany(
  {},
  [
    {
      $set: {
        "_a": {
          $map: {
            input: "$_a",
            as: "aItem",
            in: {
              $cond: [
                { $ne: ["$$aItem._p", undefined] },
                {
                  $mergeObjects: [
                    "$$aItem",
                    {
                      "_p": {
                        $cond: [
                          { $ne: ["$$aItem._p.s", undefined] },
                          {
                            $mergeObjects: [
                              "$$aItem._p",
                              {
                                "s": {
                                  $arrayToObject: {
                                    $map: {
                                      input: { $objectToArray: "$$aItem._p.s" },
                                      as: "sEntry",
                                      in: {
                                        $cond: [
                                          { $in: ["$$sEntry.k", ["a", "c", "d"]] },
                                          {
                                            k: "$$sEntry.k",
                                            v: {
                                              "t": {
                                                $filter: {
                                                  input: "$$sEntry.v.t",
                                                  as: "tItem",
                                                  cond: {
                                                    $and: [
                                                      { $ne: ["$$tItem.did", undefined] },
                                                      { $ne: ["$$tItem.dst", undefined] },
                                                      { $ne: ["$$tItem.den", undefined] }
                                                    ]
                                                  }
                                                }
                                              }
                                            }
                                          },
                                          "$$sEntry"
                                        ]
                                      }
                                    }
                                  }
                                }
                              }
                            ]
                          },
                          "$$aItem._p"
                        ]
                      }
                    }
                  ]
                },
                "$$aItem"
              ]
            }
          }
        }
      }
    }
  ]
)

方案说明

  1. 精准过滤目标元素:通过$filter对s.[a|c|d].t数组筛选,仅保留同时包含did、dst、den三个字段的对象
  2. 避免破坏非目标对象:多层$cond判断确保仅当_p.s存在时才修改该结构,无s的_p对象完全保留原有内容
  3. 防止添加null值:用$objectToArray+$map遍历s下的键值对,仅处理a/c/d键,其他键直接保留,不存在的键不会被新增null值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 14:40:33