5

I have a data set like this:

{ 
  name : 'Doc Name',
  photos: [
      {
        name: 'photo1',
        url: 'http://.....'
      },
      {
        name: 'photo2',
        url: 'http://......'
      }
   ],
   etc ...

Using Monk https://github.com/LearnBoost/monk how do I update photo2? I can use an index as I am iterating over the fields at the moment.

My current attempt below gives me an error, and I can't use a variable for the JSON selector (as in the index).

collection.update({_id: data._id}, {photos[i].data: filename}, function(err, updatedata) {

            });
Neil Lunn
  • 130,590
  • 33
  • 275
  • 280
Ryan Knell
  • 5,074
  • 2
  • 31
  • 28

2 Answers2

8

Updating items at a position in an array can be done using the positional $ operator

collection.update( 
    { _id: data.id, "photos.name": "photo2" }, 
    { $set: { "photos.$.data": "yourdata" } }
)
Neil Lunn
  • 130,590
  • 33
  • 275
  • 280
  • Of note, this only works when ONE (1) sub-document is found. If you want to update more than 1 sub-document, go vote for the bug. https://jira.mongodb.org/browse/SERVER-1243 – jnovack Apr 29 '16 at 15:41
  • @jnovack Technically that was a "feature request" and it's actually been fulfilled. There is of course a different question about that particular request [How to Update Multiple Array Elements in mongodb](https://stackoverflow.com/a/46054172/2313887), of which that link there is my answer on how you actually do that with the new MongoDB feature. – Neil Lunn Nov 01 '17 at 13:27
0

So I found a solution to my problem but there may be some better options and I will leave it unanswered. But for anyone else with the same issue this is what I did:

I extracted the MongoDB document as an object in Node.js, manipulated the document, and then replaced the entire array in a single update statement. For example here is some pseudo code:

collection.find({id: 1}, function(err, doc){
    for(i=0; i< doc.array.length; i++) {
          //do what you gotta do
          doc.array[i].property = 'new value';
    }
    collection.update({id: 1}, {$set : {"doc.array": doc.array}}, function(err,doc){
          console.log(err);
    }
})
Ryan Knell
  • 5,074
  • 2
  • 31
  • 28