简体   繁体   中英

In Mongodb subdocument array is there any way to add a new field in each subcoument

Suppose i have a document like

{
    "_id" : 5,
    "rows": [
        { "id" : "aab", "value":100},
        { "id" : "aac", "value":400},
        { "id" : "abc", "value":200},
        { "id" : "xyz", "value":300}
    ]
}

and i need to add a new key in each sub document "status" : 1 and result should be look like

{
    "_id" : 5,
    "rows": [
        { "id" : "aab", "value":100, "status":1},
        { "id" : "aac", "value":400, "status":1},
        { "id" : "abc", "value":200, "status":1},
        { "id" : "xyz", "value":300, "status":1}
    ]
}

How can i do this by single update query?

Mongo positional operator with $elemMatch having problem;

The $ operator can update the first array element that matches multiple query criteria specified with the $elemMatch() operator.

So this case using mongo query you should update only specific matching criteria. If you set rows.aac in match then you will add status:1 in row.aac array, check query as below :

db.collectionName.update({
  "_id": 5,
  "rows": {
    "$elemMatch": {
      "id": "abc"
    }
  }
}, {
  $set: {
    "rows.$.status": 1
  }
}, true, false) // here you insert new field so upsert true

mongo update showing how upsert and multi works.

But still you want to updated all documents then you should use some programming code or some script . Below code update all data using cursor forEach :

db.collectionName.find().forEach(function(data) {
  for (var ii = 0; ii < data.rows.length; ii++) {
    db.collectionName.update({
      "_id": data._id,
      "rows.id": data.rows[ii].id
    }, {
      "$set": {
        "rows.$.status": 1
      }
    }, true, false);
  }
})

If your documents size more then better way to use mongo bulk update below code shows how to updated using mongo bulk :

var bulk = db.collectionName.initializeOrderedBulkOp();
var counter = 0;
db.collectionName.find().forEach(function(data) {
  for (var ii = 0; ii < data.rows.length; ii++) {

    var updatedDocument = {
      "$set": {}
    };

    var setStatus = "rows." + ii + ".status";
    updatedDocument["$set"][setStatus] = 101;
    // queue the update
    bulk.find({
      "_id": data._id
    }).update(updatedDocument);
    counter++;
    //  re-initialize every 1000 update statements
    if (counter % 1000 == 0) {
      bulk.execute();
      bulk = db.collectionName.initializeOrderedBulkOp();
    }
  }

});
// Add the rest in the queue
if (counter % 1000 != 0)
  bulk.execute();

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