177

我惊讶地发现以下示例代码只更新了一个文档:

> db.test.save({"_id":1, "foo":"bar"});
> db.test.save({"_id":2, "foo":"bar"});

> db.test.update({"foo":"bar"}, {"$set":{"test":"success!"}});

> db.test.find({"test":"success!"}).count();
1

我知道我可以循环并不断更新,直到它们全部改变,但这似乎非常低效。有没有更好的办法?

4

13 回答 13

300

最近添加了多项更新,因此仅在开发版本 (1.1.3) 中可用。在 shell 中,您通过true将第四个参数传递给 来执行多重更新update(),其中第三个参数是 upsert 参数:

db.test.update({foo: "bar"}, {$set: {test: "success!"}}, false, true);

对于 mongodb 2.2+ 的版本,您需要设置选项 multi true 以一次更新多个文档。

db.test.update({foo: "bar"}, {$set: {test: "success!"}}, {multi: true})

对于 mongodb 3.2+ 的版本,您还可以使用 new 方法updateMany()一次更新多个文档,而无需单独的multi选项。

db.test.updateMany({foo: "bar"}, {$set: {test: "success!"}})
于 2009-11-16T05:30:38.527 回答
35

从 v3.3 开始您可以使用 updateMany

db.collection.updateMany(
   <filter>,
   <update>,
   {
     upsert: <boolean>,
     writeConcern: <document>,
     collation: <document>,
     arrayFilters: [ <filterdocument1>, ... ]
   }
)

在 v2.2 中,更新函数采用以下形式:

 db.collection.update(
   <query>,
   <update>,
   { upsert: <boolean>, multi: <boolean> }
)

https://docs.mongodb.com/manual/reference/method/db.collection.update/

于 2013-12-16T05:07:30.620 回答
18

对于Mongo 版本 > 2.2,添加一个字段 multi 并将其设置为 true

db.Collection.update({query}, 
                 {$set: {field1: "f1", field2: "f2"}},
                 {multi: true })
于 2014-10-30T06:43:31.953 回答
7

我已经创建了一种方法来使用更好的界面来做到这一点。

  • db.collection.find({ ... }).update({ ... }) -- 多更新
  • db.collection.find({ ... }).replace({ ... })-- 单次替换
  • db.collection.find({ ... }).upsert({ ... }) -- 单次插入
  • db.collection.find({ ... }).remove() -- 多重移除

您还可以通过预先链接它们来对更新和删除应用限制、跳过、排序。

如果您有兴趣,请查看Mongo-Hacker

于 2013-01-08T14:10:18.250 回答
5

在 MongoDB 客户端中,键入:

db.Collection.updateMany({}, $set: {field1: 'field1', field2: 'field2'})

3.2 版中的新功能

参数::

{}:  select all records updated

multi未采用关键字参数

于 2016-06-20T23:52:14.493 回答
4

当您发出更新命令时,MongoDB 将仅找到一个匹配查询条件的匹配文档,无论哪个文档首先匹配都会被更新,即使有更多匹配条件的文档将被忽略。

所以为了克服这个问题,我们可以在更新语句中指定“MULTI”选项,这意味着更新所有符合查询条件的文档。扫描集合中的所有文档,找到符合条件的文档并更新:

db.test.update({"foo":"bar"},{"$set":{"test":"success!"}}, {multi:true} )
于 2015-06-08T07:19:48.527 回答
4

要更新整个集合,

db.getCollection('collection_name').update({},
{$set: {"field1" : "value1", "field2" : "value2", "field3" : "value3"}},
{multi: true })
于 2020-03-15T06:04:41.430 回答
3

下面的命令可以更新一个集合的多条记录

db.collection.update({}, 
{$set:{"field" : "value"}}, 
{ multi: true, upsert: false}
)
于 2020-01-14T11:44:01.583 回答
2

所有最新版本的 mongodb updateMany()工作正常

db.getCollection('workers').updateMany({},{$set: {"assignedVehicleId" : "45680"}});
于 2017-12-25T13:55:02.393 回答
1

我有同样的问题,我找到了解决方案,它就像一个魅力

只需将标志 multi 设置为 true ,如下所示:

 db.Collection.update(
                {_id_receiver: id_receiver},
               {$set: {is_showed: true}},
                {multi: true}   /* --> multiple update */
            , function (err, updated) {...});

我希望这会有所帮助:)

于 2015-04-27T14:31:14.307 回答
1

你可以使用。`

        Model.update({
            'type': "newuser"
        }, {
            $set: {
                email: "abc@gmail.com",
                phoneNumber:"0123456789"
            }
        }, {
            multi: true
        },
        function(err, result) {
            console.log(result);
            console.log(err);
        })  `
于 2016-03-24T12:27:46.910 回答
1

updateMany() 方法具有以下形式:

db.collection.updateMany(
   <filter>,
   <update>,
   {
     upsert: <boolean>,
     writeConcern: <document>,
     collation: <document>,
     arrayFilters: [ <filterdocument1>, ... ],
     hint:  <document|string>        // Available starting in MongoDB 4.2.1
   }
)

餐厅集合包含以下文件:

{ "_id" : 1, "name" : "Central Perk Cafe", "violations" : 3 }
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "violations" : 2 }
{ "_id" : 3, "name" : "Empire State Sub", "violations" : 5 }
{ "_id" : 4, "name" : "Pizza Rat's Pizzaria", "violations" : 8 }

以下操作会更新所有违规次数大于 4 的文档并 $set 一个标志以供审核:

try {
   db.restaurant.updateMany(
      { violations: { $gt: 4 } },
      { $set: { "Review" : true } }
   );
} catch (e) {
   print(e);
}
于 2021-09-05T11:35:50.557 回答
-1

感谢分享这个,我用 2.6.7 和下面的查询刚刚工作,

对于所有文档:

db.screen.update({stat:"PRO"} , {$set : {stat:"pro"}}, {multi:true})

对于单个文档:

db.screen.update({stat:"PRO"} , {$set : {stat:"pro"}}, {multi:false})
于 2015-02-07T15:59:50.047 回答