arrays - 如何在 mongodb 中更新多个数组元素

我有一个包含元素数组的 Mongo 文档。

我想重置 .profile = XX 的数组中所有对象的 .handled 属性。

文档格式如下:

{
    "_id": ObjectId("4d2d8deff4e6c1d71fc29a07"),
    "user_id": "714638ba-2e08-2168-2b99-00002f3d43c0",
    "events": [{
            "handled": 1,
            "profile": 10,
            "data": "....."
        } {
            "handled": 1,
            "profile": 10,
            "data": "....."
        } {
            "handled": 1,
            "profile": 20,
            "data": "....."
        }
        ...
    ]
}

所以,我尝试了以下方法:

.update({"events.profile":10},{$set:{"events.$.handled":0}},false,true)

但是它只更新每个文档中第一个匹配的数组元素。 (这是 $ - the positional operator 的定义行为。)

如何更新所有匹配的数组元素?

最佳答案

使用 release of MongoDB 3.6 (并且在 MongoDB 3.5.12 的开发分支中可用)您现在可以在单个请求中更新多个数组元素。

这使用 filtered positional $[<identifier>] 此版本中引入的更新运算符语法:

db.collection.update(
  { "events.profile":10 },
  { "$set": { "events.$[elem].handled": 0 } },
  { "arrayFilters": [{ "elem.profile": 10 }], "multi": true }
)

"arrayFilters"传递给 .update() 的选项甚至 .updateOne() , .updateMany() , .findOneAndUpdate().bulkWrite() 方法指定要匹配更新语句中给出的标识符的条件。任何符合给定条件的元素都会被更新。

注意到 "multi"正如在问题的上下文中给出的那样,用于期望这将“更新多个元素”,但事实并非如此,现在仍然不是。此处的用法适用于 “多个文档”,一直如此,或者现在以其他方式指定为 .updateMany() 的强制设置在现代 API 版本中。

NOTE Somewhat ironically, since this is specified in the "options" argument for .update() and like methods, the syntax is generally compatible with all recent release driver versions.

However this is not true of the mongo shell, since the way the method is implemented there ( "ironically for backward compatibility" ) the arrayFilters argument is not recognized and removed by an internal method that parses the options in order to deliver "backward compatibility" with prior MongoDB server versions and a "legacy" .update() API call syntax.

So if you want to use the command in the mongo shell or other "shell based" products ( notably Robo 3T ) you need a latest version from either the development branch or production release as of 3.6 or greater.

另见 positional all $[] 它还更新“多个数组元素”,但不应用于指定条件,并应用于数组中所需操作的 所有 元素。

另见 Updating a Nested Array with MongoDB了解这些新的位置运算符如何应用于“嵌套”数组结构,其中“数组在其他数组中”。

IMPORTANT - Upgraded installations from previous versions "may" have not enabled MongoDB features, which can also cause statements to fail. You should ensure your upgrade procedure is complete with details such as index upgrades and then run

   db.adminCommand( { setFeatureCompatibilityVersion: "3.6" } )

Or higher version as is applicable to your installed version. i.e "4.0" for version 4 and onwards at present. This enabled such features as the new positional update operators and others. You can also check with:

   db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )

To return the current setting

https://stackoverflow.com/questions/4669178/

相关文章:

mongodb - 在两个不同的集合中生成重复的 Mongo ObjectId 的可能性?

MongoDB - 管理员用户未授权

mongodb - 更改 MongoDB 数据存储目录

datetime - 在 mongodb 中存储日期/时间的最佳方法

mongodb - MongoDB 的命名约定是什么?

database - MongoDB 中的 findAndModify 和 update 有什么区别

macos - mongodb,macos - 限制警告

mongodb - 减少 MongoDB 数据库文件大小

mongodb - 无法启动 mongodb 本地服务器

node.js - 比较 Mongoose _id和字符串