MongoDB updateMany()

MongoDB updateMany function comes with plenty options.  In MongoDB if you want to update bulk documents you use db.collection.updateMany() method to update all documents that matches the criteria you specify for a collection.

Use case for updateMany method:

Let’s say we have a collection users which contains following documents:

{ "_id" : 1, "name" : "Mark", "role" : "admin" }
{ "_id" : 2, "name" : "John", "role" : "user" }
{ "_id" : 3, "name" : "Andrew", "role" : "user" }

We have 3 users in our collection. We made a mistake and we would like to replace user role with a client role.

We know that 2 documents have user role.

To update both user documents in one go we will write below MongoDB query:

db.users.updateMany( 
    { role: "user" },
    { $set: { role: "client" } }
)

Result from MongoDB:

{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }

MongoDB acknowledged that 2 documents were updated using updateMany method.

We can verify this by running following query:

db.users.find()

User collection Output:

{ "_id" : 1, "name" : "Mark", "role" : "admin" }
{ "_id" : 2, "name" : "John", "role" : "client" }
{ "_id" : 3, "name" : "Andrew", "role" : "client" }

How to use Upsert in MongoDB updateMany() query?

In MongoDB, updateMany() method accepts an upsert parameter that let’s you insert a document a document if it does not exists in the collection.

When you set upsert : true in the second argument, any documents that matches the conditions will be updated and if there is no match found a new document will be inserted.

We can take our users collection as an example:

{ "_id" : 1, "name" : "Mark", "role" : "admin" }
{ "_id" : 2, "name" : "John", "role" : "user" }
{ "_id" : 3, "name" : "Andrew", "role" : "user" }

Upsert query example in MongoDB updateMany() method:

db.users.updateMany(
{ name: "Matt" },
{ $set: { role: "admin" } },
{ upsert: true }
)

Response of upsert:

{
"acknowledged" : true,
"matchedCount" : 0,
"modifiedCount" : 0,
"upsertedId" : ObjectId("5d9fa8f67696a9ba894e465c")
}

In the above query no document matched our criteria so a user name Matt with role admin is upserted.

Now, if we check the users collection agian, we will see Matt document will be present.

db.users.find()

Result

{ "_id" : 1, "name" : "Mark", "role" : "admin" }
{ "_id" : 2, "name" : "John", "role" : "user" }
{ "_id" : 3, "name" : "Andrew", "role" : "user" } 
{ "_id" : ObjectId("5d59c33391ce2235180011e8"), "name" : "Matt", "role" : "admin" }

How to update Embedded Documents using MongoDB updateMany method?

Similar to updating a document as we did above we can also update embedded documents using db.collection.updateMany()method.

Let’s insert two user documents:

db.users.insertMany([
    {
        "_id" : 1,
        "name" : "Mark",
        "role" : "admin",
        "settings" : {
            "logo" : "http://url.com/logo.gif",
            "width" : "200px",
            "height" : "400px",
            "background" : "red",
        }
    },  
    {
        "_id" : 2,
        "name" : "John",
        "role" : "user",
        "settings" : {
            "logo" : "https://domain.com/mylogo.png",
            "width" : "500px",
            "height" : "300px",
            "background" : "white",
        }
    }
])

Now, let’s say we want to update the background field inside settings to yellow of all users whose role is user. We can use the following code to update the embedded document using updateMany method.

db.users.updateMany({ 
    role: "user" 
    }, { 
        $set: { 
            "settings.background": "yellow"
        } 
})

Result

{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 } 

Since, we had only one document matching our criteria so only one user sub document updated using MongoDB updateMany method.

Now, let’s check the document to see if it’s updated.

db.users.find({
    role: "user"
    }).pretty()

Result

{
        "_id" : 2,
        "name" : "John",
        "role" : "user",
        "settings" : {
            "logo" : "https://domain.com/mylogo.png",
            "width" : "500px",
            "height" : "300px",
            "background" : "yellow",
        }
    }

Sure enough, we can see our only one user document settings is updated.

How to update Arrays using MongoDB updateMany() method?

Similar to subdocument update we can update Arrays using MongoDB updateMany method but the only difference here is that we will use array index which we want to update. Let’s check below example:

Let’s say we have students collection which have marks an array with the following documents:

{ "_id" : 1, "marks" : [ 10, 25, 53 ] }
{ "_id" : 2, "marks" : [ 70, 66, 33 ] }
{ "_id" : 3, "marks" : [ 95, 22, 11 ] }

Now, we want to update marks array whose _id is 2. To do that we will use following query:

db.students.updateMany({_id: 2}, 
{ 
        $set: {
            "marks.0": 80, 
            "marks.1": 99
        } 
})

Result:

{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

Now if we retrieve our documents we will see mongodb updateMany only updated _id:2 document because we specified that in our condition.

db.students.find()

Result:

{ "_id" : 1, "marks" : [ 10, 25, 53 ] }
{ "_id" : 2, "marks" : [ 80, 99, 33 ] }
{ "_id" : 3, "marks" : [ 95, 22, 11 ] }

How to use arrayFilters Parameter in MongoDB UpdateMany?

Let’s say  you only to want to update array elements which has value higher than 95. To achieve that we will use arrayFilters and the positional $ operator to check which element in the array to update.

We will use our previous documents as an example:

{ "_id" : 1, "marks" : [ 10, 25, 53 ] }
{ "_id" : 2, "marks" : [ 80, 99, 33 ] }
{ "_id" : 3, "marks" : [ 95, 22, 11 ] } 

We will run the following query to update array elements which have 95 or higher value.

db.students.updateMany(
{ marks: { $gte: 95 } },
{ $set: { "scores.$[e]" : 100} },
{ arrayFilters: [ { "e": { $gte: 95} } ] }
)

Result:

{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }

We have only 2 documents which had 95 or higher values so only two document updated using updateMany function.

Let’s check our updated documents.

db.students.find()

Result:

{ "_id" : 1, "marks" : [ 10, 25, 53 ] }
{ "_id" : 2, "marks" : [ 80, 100, 33 ] }
{ "_id" : 3, "marks" : [ 100, 22, 11 ] }

How to use MongoDB UpdateMany In Laravel 9?

To use the MongoDB updateMany function in the Laravel 9, you have to use jessenger mongodb package in your Laravel app. Install the package from this link. Now, let’s say you want to update all users whose country is United States to US. To do that you will write following code:


User::where('country','United States')->update('country','US');

Make sure that you have changed User’s Eloquent Model to Jenssegers\Mongodb\Eloquent\Model; so your User class will look like this:


use Jenssegers\Mongodb\Eloquent\Model;

class User Extends Model
{
}

If you would like to learn more about MongoDB updateMany function you can check mongodb documentation.

Leave your feedbacks or questions in the comments below and we will do our best to answer soon.