在 mongodb 中更新查询时覆盖值并创建键

Overwrite value and create key while update query in mongodb

我有一个 mongodb 集合,如下所示:

{
     "_id" : ObjectId("60471bd482c0da3c0e70d26f"),
     "owner" : "John",
     "propAvailable" : {
        "val1" : true
    }
},
{
    "_id" : ObjectId("60471bd482c0da3c0e76523f"),
    "owner" : "Matt",
    "propAvailable" : {
    "val1" : {
       "val2" : true  
    }
}

我需要 运行 对此集合进行更新查询,以更新 'propAvailable' 键的值,这样

db.collection('props').update({'owner' : 'John'} , {$set : {'propAvailable.val1.val2' : true}});

如果文档看起来像第二个文档但出现错误,则此查询有效: 如果文档格式是第一个,则无法在元素 {'val1': true} 中创建字段 'val2'。有没有一种方法可以编写此查询,以便它覆盖布尔值 'true' 并将其替换为对象 {'val2' : true}

您可以使用:

db.collection.update({
  "owner": "John"
},
{
  $set: {
    "propAvailable.val1": {
      val2: true
    }
  }
})

propAvailable.val1 中创建 val2: true 并替换其当前内容。

如您所见,正在 playground

如果您使用的是 Mongo 4.2+ 版,您可以使用流水线更新来实现这一点,如下所示:

db.collection.updateMany({
  owner: "John"
},
[
  {
    $set: {
      "propAvailable.val1": {
        $mergeObjects: [
          {
            $cond: [
              {
                $eq: [
                  "object",
                  {
                    $type: "$propAvailable.val1"
                  }
                ]
              },
              "$propAvailable.val1",
              {}
            ]
          },
          {
            val2: true
          }
        ]
      }
    }
  },
])

Mongo Playground

对于较旧的 mongo 版本,如果对象在 val1 下可能有您想要保留的其他字段,则不可能在 1 个查询中执行此操作。您将不得不阅读和更新,或者针对每种情况执行两次不同的更新。