How to update value of a key in a list of a json in Mongo

Shalu picture Shalu · May 23, 2014 · Viewed 13.4k times · Source

I have a document---

   Employees:[
       {
          name:"abc",
          contact:"123",
          email:"[email protected]"
       },
       {
          name:"efg",
          contact:"456",
          email:"[email protected]"
       },
       {
          name:"hij",
          contact:"789",
          email:"[email protected]"
       }
  ]

I need to update name with value= "abc" for all the keys name in the list.

I have tried to update like

db.collection.update(
    { "_id" : ObjectId("5308595e3256e758757b4d2f") }, 
    { "$set": { "Employees.name " : "abc" } } 
);

But getting the error: cannot use the part (Employees of Employees.name) to traverse the element.

Answer

Neil Lunn picture Neil Lunn · May 23, 2014

These are in an array, so that is why your current statement does not work. You have a few options to do this as there is no simple statement to do this.

1. You know how many elements are in the array, so set them explicitly with "dot-notation"

    db.collection.update(
        { "_id" : ObjectId("5308595e3256e758757b4d2f") }, 
        { 
            "$set": { 
                "Employees.0.name " : "abc",
                "Employees.1.name " : "abc",
                "Employees.2.name " : "abc"
            }
        } 
    );

2. You don't know but are prepared to issue this update until the returned "modified" documents becomes 0. Then you can use a positional $ operator in the update but this will only ever match one element at a time:

     db.collection.update(
        { 
            "_id" : ObjectId("5308595e3256e758757b4d2f"),
            "Employees.name": { "$ne": "abc" }
        }, 
        { 
            "$set": { 
                "Employees.$.name " : "abc"
            }
        } 
    );

3. Retrieve the document and update all the array members in code:

    var doc = db.collection.findOne({ 
        "_id": ObjectId("5308595e3256e758757b4d2f") 
    });

    doc.Employee.forEach(function(emp) {
        emp.name = "abc";
    });
    db.collection.update(
       { "_id": doc._id },
       { "$set": { "Employee": doc.Employeee } }
    )

Those are the basic methods and doing this, along with some practical example of why this cannot be presently done in a single statement just updating every array member field.