【问题标题】:Mongodb Update subdocument values matching subdocument and without altering other fieldsMongodb更新与子文档匹配的子文档值并且不更改其他字段
【发布时间】:2021-01-28 18:57:30
【问题描述】:

我有这样的架构

{
    "_id": "5f86da4b5bb9a62742371409",
    "status" : true,
    "doc": [
      {
        "_id": "5f86cacbe4d7c423f21faf50",
        "a": 4,
        "b": null
      },
      {
        "_id": "5f86cb01a1ca5124063299c1",
        "a": 6,
        "b": null

      }
    ]
}

我有一个更新的形式


[
      {
        "_id": "5f86cacbe4d7c423f21faf50",
        "b": 90
      },
      {
        "_id": "5f86cb01a1ca5124063299c1",
        "b": 45

      }
    ]

我怎样才能更新这个集合以得到这样的结果?

{
    "_id": "5f86da4b5bb9a62742371409",
    "status" : true,
    "doc": [
      {
        "_id": "5f86cacbe4d7c423f21faf50",
        "a": 4,
        "b": 90
      },
      {
        "_id": "5f86cb01a1ca5124063299c1",
        "a": 6,
        "b": 45

      }
    ]
}

基本上我只想用特定键更新子文档(其他键保持不变)

【问题讨论】:

    标签: mongodb mongoose subdocument


    【解决方案1】:

    您可以使用 MongoDB 4.2 中的 update with aggregation pipeline

    • $map 迭代数组doc 的循环并在其中迭代updateDocs 数组,它将返回匹配的b,然后$mergeObjects 将返回更新的文档,
    let updateDocs = [
      { "_id": mongoose.Types.ObjectId("5f86cacbe4d7c423f21faf50"), "b": 90 },
      { "_id": mongoose.Types.ObjectId("5f86cb01a1ca5124063299c1"), "b": 45 }
    ];
    
    db.collection.updateMany({},
    [
      {
        $set: {
          doc: {
            $map: {
              input: "$doc",
              as: "d",
              in: {
                $mergeObjects: [
                  "$$d",
                  {
                    $reduce: {
                      input: updateDocs,
                      initialValue: {},
                      in: {
                        $cond: [
                          { $eq: ["$$this._id", "$$d._id"] },
                          { b: "$$this.b" },
                          "$$value"
                        ]
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      }
    ]
    )
    

    Playground

    【讨论】:

    • 在我的实际数据集中似乎不起作用,但无论如何感谢。它给了我一些想法。 ibb.co/S03yRmB
    • 你需要传递ObjectId,目前它的字符串只是包裹它ObjectId("5f86cacbe4d7c423f21faf50")然后尝试。
    • 顺便说一句,你在$set 周围缺少一个数组包装器[],没有它它不会更新数据库。
    猜你喜欢
    • 2017-05-28
    • 2021-02-25
    • 2011-08-04
    • 2019-09-18
    • 2016-08-18
    • 1970-01-01
    • 2013-01-06
    • 1970-01-01
    相关资源
    最近更新 更多