简体   繁体   中英

Push field to each element of object array (MongoDB)

Let's say I have some documents of such type:

{ 
 _id: ObjectId("5abe0f5add80a30001eff68d"),
 obj_array: [ 
     { 
       a: 1,
       b: "some", 
       c: 134
     },
     { 
       a: 2, 
       b: "aaa",
       c: 564
     }
   ]
} 

What I need to do is to update all the obj_array elements by pushing a new field d: "new_value" . Expected result:

 { 
 _id: ObjectId("5abe0f5add80a30001eff68d"),
 obj_array: [ 
     { 
       a: 1,
       b: "some", 
       c: 134,
       d: "new_value"
     },
     { 
       a: 2, 
       b: "aaa",
       c: 564,
       d: "new_value"
     }
   ]
} 

I didn't find any other solution but constructing new obj_array object and setting doc.obj_array with the new array. I wonder is there some more elegant way to do that? Here's my code:

myTable.find().forEach(function(document) {
    var new_array = [];
    document.obj_array.forEach(function(elem) {
        elem.d = "new_value";
        new_array.push(elem);
    })
    myTable.update({_id: document._id}, {$set: {obj_array: new_array}})
})

You can use $[] the all positional operator which updates all the elements in an array

myTable.update(
  { "_id": document._id },
  { "$set": { "obj_array.$[].d": "new_value" }}
)

1: run command npm install async --save

db.collection.find({_id:ObjectId("5abe0f5add80a30001eff68d")},function(err, result){
   if(result){
     async.eachSeries(result.obj_array,function(value, cb){
       value.d = "new_value";
       return cb();
     },function(){
       console.log(result)
     })
   }
})
//Once you get perfect result you can execute update query
db.collection.update({_id:ObjectId("5abe0f5add80a30001eff68d")},result)

NOTE: If you work with nodeJS then you need to install async, if you work with core javascript then you can change to common for-each loop.

its always work for me :)

You can simply achieve this by traverse array through $[] and update it:

for single update:

db.getCollection('test').update({},{ "$set": { "array.$[].key": "Value" }})

multiple updates:

db.getCollection('test').updateMany({},{ "$set": { "array.$[].key": "Value" }})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM