Mongodb更新与子文档匹配的子文档值并且不更改其他字段

Posted

技术标签:

【中文标题】Mongodb更新与子文档匹配的子文档值并且不更改其他字段【英文标题】:Mongodb Update subdocument values matching subdocument and without altering other fields 【发布时间】: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

      
    ]

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

【问题讨论】:

【参考方案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 周围缺少一个数组包装器[],没有它它不会更新数据库。

以上是关于Mongodb更新与子文档匹配的子文档值并且不更改其他字段的主要内容,如果未能解决你的问题,请参考以下文章

如何匹配MongoDB中的子文档数组?

MongoDB更新文档

如何从 mongodb 通过 Geowithin 获取匹配的子文档?

使用 findOne 更新 mongoDB 文档中的子字段并保存

如何更新 MongoDB 中的子文档?

获取数组中每个索引的子文档元素计数并更新子文档键 - 数组中的子文档(IN MONGODB)