Mongodb 更新匹配子文档的子文档值而不改变其他字段

Mongodb Update subdocument values matching subdocument and without altering other fields

我有这样的模式

{
    "_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

      }
    ]

我怎样才能将 collection 更新为这样的结果?

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

      }
    ]
}

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

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

  • $map 迭代数组 doc 的循环并在其中迭代 updateDocs 数组,它将 return 匹配 b,然后 $mergeObjects 将 return 更新文档,
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