1

How can an existing document be updated using it's own values?

A collection of Album exists which contains photos, the photo webpath needs modifying to prepend the existing value.

The following is based on the answer https://stackoverflow.com/a/3792958/1283381

The code below fails to update the webPath value.

db.getCollection('Album').find().snapshot().forEach(
      function (e) {
        for(var i=0; i<e.photos.length; i++) {
            e.photos[i].webPath = '/uploads'+e.photos[i].webPath;
        }
            db.events.save(e);
    }
)

Output is:

Updated 1 existing record(s) in 2ms

Edit 1

Sample Album document:

{
    "_id" : ObjectId("5923e3eebe37843815248521"),
    "created" : ISODate("2017-05-23T07:25:34.000Z"),
    "photos" : [ 
    {
        "id" : 474,
        "webPath" : "/dir/to.jpg"
    }, 
    {
        "id" : 475,
        "webPath" : "/dir/to.jpg"
    }
    ]
}
lookbadgers
  • 988
  • 9
  • 31

1 Answers1

0

You're saving to the wrong collection.

After you loop over your photos and update the data, you have this line:

db.events.save(e);

I expect you were intending to save back to the original collection you queried from. However this is saving to the events collection (and creating it if it doesn't exist) because both of the following lines are equivalent (see MongoDB docs). You'll likely find you've got an events collection full of your modified data.

db.foo.save(x);
db.getCollection('foo').save();

Instead, you'll want to make sure you're saving back to the original collection you're querying (the Album collection). In your case, this can simply be a change to:

db.getCollection('Album').save(e);

Your full snippet would look like this:

db.getCollection('Album').find().snapshot().forEach(
      function (e) {
        for(var i=0; i<e.photos.length; i++) {
            e.photos[i].webPath = '/uploads'+e.photos[i].webPath;
        }
        db.getCollection('Album').save(e);
    }
)
Mark Embling
  • 12,605
  • 8
  • 39
  • 53