多个mongo更新运算符在一个语句中?

ber*_*tie 16 mongodb

我可以在一个声明中结合使用$ pushAll和$ inc吗?

在结合之前,这很好用:

db.createCollection("test");
db.test.insert({"name" : "albert", "bugs" : []});

db.test.update({"name":"albert"}, 
    {"$pushAll" : {"bugs" : [{"name":"bug1", "count":1}]}});

db.test.update({"name":"albert"}, 
    {"$inc" : {"bugs.0.count" : 1}});

db.test.update({"name":"albert"}, 
    {"$pushAll" : {"bugs" : [{"name":"bug2", "count":1}]}});
Run Code Online (Sandbox Code Playgroud)

但是当我尝试将它组合起来时:

db.createCollection("test");
db.test.insert({"name" : "albert", "bugs" : []});

db.test.update({"name":"albert"}, 
    {"$pushAll" : {"bugs" : [{"name":"bug1", "count":1}]}});

db.test.update({"name":"albert"}, 
    {
       "$pushAll" : {"bugs" : [{"name":"bug2", "count":1}]}, 
       "$inc" : {"bugs.0.count" : 1}
    }
);
Run Code Online (Sandbox Code Playgroud)

发生此错误:

have conflicting mods in update
Run Code Online (Sandbox Code Playgroud)

我想这有可能做到这一点,而且,我想象的不仅仅是pushAll和inc,但我不确定这是否得到支持?


2012年3月23日更新

我在一个数组的不同元素上尝试了多个$ inc,它有效(虽然不正确.引用下面的答案,以澄清为什么这个doensnt运行良好,有效的方法The correct way to increment both fields is as follows: > db.test.update({"name":"albert"}, {"$inc" : {"bugs.0.count" : 1, "bugs.1.count" : 1}}):

db.test.update({"name":"albert"}, 
  {
    "$inc" : {"bugs.0.count" : 1}, 
    "$inc" : {"bugs.1.count" : 1}
  }
);
Run Code Online (Sandbox Code Playgroud)

$ set和$ inc在数组的不同元素上的组合也有效:

db.test.update({"name":"albert"}, 
  {
    "$set" : {"bugs.0.test" : {"name" : "haha"}}, 
    "$inc" : {"bugs.0.count" : 1}, 
    "$inc" : {"bugs.1.count" : 1}
  }
);
Run Code Online (Sandbox Code Playgroud)

但是将这些中的任何一个与$ push或$ pushAll结合起来,都会出错.

所以,我目前的结论是,它不是关于同一阵列中的多个元素的多个操作是问题,但是将这些操作与$ push或$ pushAll组合可以改变阵列是问题.

Mar*_*arc 22

可以对同一文档执行多次更新,只要这些更新不冲突(因此"更新中存在冲突的mod"错误).

因为"$ push":{"bugs":[{"name":"bug1","count":1}]}和"$ inc":{"bugs.0.count":1}都试图修改文档的相同部分(即"bug"数组),它们发生冲突.

如果每个更新都影响文档的不同部分,则可以组合多个更新:

例如:

> db.test.drop()
true
> db.test.save({ "_id" : 1, "name" : "albert", "bugs" : [ ] })
> db.test.update({"name":"albert"}, {"$pushAll" : {"bugs" : [{"name":"bug1", "count":1}]}, "$inc" : {"increment" : 1}, $set:{"note":"Here is another field."}})
> db.test.find()
{ "_id" : 1, "bugs" : [ { "name" : "bug1", "count" : 1 } ], "increment" : 1, "name" : "albert", "note" : "Here is another field." }
> 
Run Code Online (Sandbox Code Playgroud)

该更新包含三个不同的操作($ pushAll,$ inc和$ set),但能够成功完成,因为每个操作都会影响文档的不同部分.

我意识到这并不是您希望做的,但希望它能让您更好地了解更新的工作原理,并提供一些想法,了解如何重新构建更新和/或文档以执行您的功能.申请要求.祝好运.

  • 正如您所发现的,只要更新不冲突,就可以同时更新数组中的多个元素.冲突来自于尝试在修改其中一个元素的同时更改数组的大小.顺便说一句,你可能会注意到更新"{"$ inc":{"bugs.0.count":1},"$ inc":{"bugs.1.count":1}}"不起作用正如所料.(这是因为更新文档有一个重复键,"$ inc".)增加两个字段的正确方法如下:> db.test.update({"name":"albert"},{"$ inc ":{"bugs.0.count":1,"bugs.1.count":1}}) (4认同)