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

2024-05-23 18:06:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个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定义的行为。)

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


Tags: 对象文档id元素data属性mongo数组
3条回答

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

这将使用此版本中引入的filtered positional ^{}更新运算符语法:

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

传递给^{}或偶数个选项的"arrayFilters"^{}^{}^{}^{}方法指定要在update语句中给定的标识符上匹配的条件。任何符合给定条件的元素都将被更新。

注意到问题上下文中给出的"multi"是在预期这将“更新多个元素”的情况下使用的,但事实并非如此。这里的用法适用于“多个文档”,就像以前一样,或者现在在现代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.

另请参见^{},它也会更新“多个数组元素”,但不应用于指定的条件,并应用于数组中的所有元素,其中这是所需的操作。

另请参见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

对我有用的是:

db.collection.find({ _id: ObjectId('4d2d8deff4e6c1d71fc29a07') })
  .forEach(function (doc) {
    doc.events.forEach(function (event) {
      if (event.profile === 10) {
        event.handled=0;
      }
    });
    db.collection.save(doc);
  });

我认为对于mongo新手和熟悉JQuery&friends的任何人来说,这一点都比较清楚。

此时无法使用位置运算符更新数组中的所有项。见吉拉http://jira.mongodb.org/browse/SERVER-1243

作为一项工作,你可以:

  • 单独更新每个项目 (事件0.handled事件1.handled …)或。。。
  • 阅读文档,进行编辑 手动保存替换 旧的(如果要确保 原子更新)

相关问题 更多 >