3

I have a document like following in my stocks collection in mongodb.

{ _id: 'xRMuRBhqRLgASyQyW',
  History: 
     [ { orderId: '12032017001877',
         status: 'COMPLETED',
        },
       { orderId: '22122017002450', 
        status: 'PROCESSED',
        },
        { orderId: '22122018002450', 
        status: 'DEPOSIT',
        }  
     ] 
 }

I want to iterate through all document in stocks collection and add a field flag: true if status is not 'PROCESSED'.

Ashh
  • 44,693
  • 14
  • 105
  • 132
Mritunjay Upadhyay
  • 1,004
  • 1
  • 15
  • 27

4 Answers4

14

You need to use the all $[] positional operator to update each element in the array

db.collection.update(
   { "History": { "$elemMatch": { "status": { "$ne": "PROCESSED" } } } }, 
   { "$set": { "History.$[].flag": false } },
   { "multi": true }
)
Ashh
  • 44,693
  • 14
  • 105
  • 132
2

You can achieve it using script.

db.stocks.find().forEach(function (e) {
  var modified = false;
  e.History.forEach(function (o) {
    if (o.status != "PROCESSED") {
      o.flag = true;
      modified = true;
    }
  });
  if (modified) {
    db.stocks.save(e);
  }
});
Vikas
  • 51
  • 4
1

You can simply do it by using '$' operator. Something like:

 db.stocks.update( {"history.status" : { $not: "PROCESSED" } , 
                { $set: {"history.$.flag": true }} , 
                false , 
                true);
Pouya Jabbarisani
  • 1,084
  • 3
  • 16
  • 29
0

My answer is very similar @Anthony but a two extra parameter( for upsert and multi) are added. For reference You can check official document.

db.stocks.update(
    { "History": { "$elemMatch": { "status": { "$ne": "PROCESSED" } } } }, 
    { "$set": { "History.$[].flag": false }},
     false,              // show that if there is not any document with specified criteria , it will not create a new document.
     ture              // according to document of mongodb if multi is true then more than one document will be updated, other wise only one document will be updated.
)
Mritunjay Upadhyay
  • 1,004
  • 1
  • 15
  • 27