196

I was surprised to find that the following example code only updates a single document:

> 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

I know I can loop through and keep updating until they're all changed, but that seems terribly inefficient. Is there a better way?

Community
  • 1
  • 1
Luke Dennis
  • 14,212
  • 17
  • 56
  • 69

13 Answers13

328

Multi update was added recently, so is only available in the development releases (1.1.3). From the shell you do a multi update by passing true as the fourth argument to update(), where the the third argument is the upsert argument:

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

For versions of mongodb 2.2+ you need to set option multi true to update multiple documents at once.

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

For versions of mongodb 3.2+ you can also use new method updateMany() to update multiple documents at once, without the need of separate multi option.

db.test.updateMany({foo: "bar"}, {$set: {test: "success!"}})
Alex Blex
  • 34,704
  • 7
  • 48
  • 75
mdirolf
  • 7,521
  • 2
  • 23
  • 15
  • 3
    I'm not sure about when this change happened but, Mongodb v2.2.2 does this a bit differently. db.collection.update( , , ) where options is a set of key value pairs. See documentation: http://docs.mongodb.org/manual/applications/update/ – TechplexEngineer Dec 23 '12 at 15:08
  • 11
    what if I want set set different values to different document? is there a alegant way of doing this? – zach Aug 15 '13 at 04:09
  • How to do it for oldvalue+"some string" – Mahesh K Nov 14 '17 at 11:03
  • `update_many` for pymongo. smh. – ajsp Dec 14 '22 at 01:55
37

Starting in v3.3 You can use updateMany

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

In v2.2, the update function takes the following form:

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

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

user602525
  • 3,126
  • 4
  • 25
  • 40
18

For Mongo version > 2.2, add a field multi and set it to true

db.Collection.update({query}, 
                 {$set: {field1: "f1", field2: "f2"}},
                 {multi: true })
zero
  • 701
  • 2
  • 8
  • 13
9

I've created a way to do this with a better interface.

  • db.collection.find({ ... }).update({ ... }) -- multi update
  • db.collection.find({ ... }).replace({ ... }) -- single replacement
  • db.collection.find({ ... }).upsert({ ... }) -- single upsert
  • db.collection.find({ ... }).remove() -- multi remove

You can also apply limit, skip, sort to the updates and removes by chaining them in beforehand.

If you are interested, check out Mongo-Hacker

Tyler Brock
  • 29,626
  • 15
  • 79
  • 79
  • 2
    TypeError: db.getCollection(...).find(...).update is not a function : ? – Anthony Jan 06 '17 at 05:45
  • 1
    didn't worked `db.userActivity.find({ 'appId' : 1234, 'status' : 1}).update({ $set: { 'status': 1 } }); 2017-06-05T17:47:10.038+0530 E QUERY [thread1] TypeError: db.userActivity.find(...).update is not a function :` – Prakash P Jun 05 '17 at 12:17
  • 1
    @Tyler explained, that the syntax he proposes works with the Mongo-Hacker he built - not out of the box. – Nico Aug 04 '21 at 09:17
7

To Update Entire Collection,

db.getCollection('collection_name').update({},
{$set: {"field1" : "value1", "field2" : "value2", "field3" : "value3"}},
{multi: true })
Isuru Amarathunga
  • 2,127
  • 1
  • 20
  • 20
5

In the MongoDB Client, type:

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

New in version 3.2

Params::

{}:  select all records updated

Keyword argument multi not taken

Boseam
  • 165
  • 2
  • 2
4

MongoDB will find only one matching document which matches the query criteria when you are issuing an update command, whichever document matches first happens to be get updated, even if there are more documents which matches the criteria will get ignored.

so to overcome this we can specify "MULTI" option in your update statement, meaning update all those documnets which matches the query criteria. scan for all the documnets in collection finding those which matches the criteria and update :

db.test.update({"foo":"bar"},{"$set":{"test":"success!"}}, {multi:true} )
Yathish Manjunath
  • 1,919
  • 1
  • 13
  • 23
4

The updateMany() method has the following form:

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

The restaurant collection contains the following documents:

{ "_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 }

The following operation updates all documents where violations are greater than 4 and $set a flag for review:

try {
   db.restaurant.updateMany(
      { violations: { $gt: 4 } },
      { $set: { "Review" : true } }
   );
} catch (e) {
   print(e);
}
MD SHAYON
  • 7,001
  • 45
  • 38
3

The following command can update multiple records of a collection

db.collection.update({}, 
{$set:{"field" : "value"}}, 
{ multi: true, upsert: false}
)
2

All latest versions of mongodb updateMany() is working fine

db.getCollection('workers').updateMany({},{$set: {"assignedVehicleId" : "45680"}});
KARTHIKEYAN.A
  • 18,210
  • 6
  • 124
  • 133
1

I had the same problem , and i found the solution , and it works like a charm

just set the flag multi to true like this :

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

i hope that helps :)

Aouidane Med Amine
  • 1,571
  • 16
  • 17
1

You can use.`

        Model.update({
            'type': "newuser"
        }, {
            $set: {
                email: "abc@gmail.com",
                phoneNumber:"0123456789"
            }
        }, {
            multi: true
        },
        function(err, result) {
            console.log(result);
            console.log(err);
        })  `
Jitendra
  • 189
  • 2
  • 7
-1

Thanks for sharing this, I used with 2.6.7 and following query just worked,

for all docs:

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

for single doc:

db.screen.update({stat:"PRO"} , {$set : {stat:"pro"}}, {multi:false})
Athar
  • 579
  • 5
  • 12