Search code examples
mongodbembedded-documents

MongoDB How to add a field to ALL embedded documents in an array


If I have some documents inside a collection. In this format:

{posts: [{"name": "post1"},..., {"name": "postN"}]}

What is the equivalent of this function:

db.my_collection.update({}, { $set: {"posts.0.lastMod": new Date()}}, false, true)

But to update all the embedded documents instead of only position 0? I have tried doing:

db.my_collection.update({}, { $set: {"posts.lastMod": new Date()}}, false, true)

But that just gave me an error already on the first document:

WriteResult({
    "nMatched" : 0,
    "nUpserted" : 0,
    "nModified" : 0,
    "writeError" : {
        "code" : 28,
        "errmsg" : "Cannot create field 'lastMod' in element {posts: [ALL MY ARRAY WAS PRINTED HERE]"

Solution

  • The answer in the comments above is 99% there. This makes it a tad safer by ensuring it will only use the dotpath trick to add lastMod to an existing array of posts. If posts does not exist, without the predicate it will create a brand new single object posts which is probably not desired.

    db.foo.updateMany(
        {posts: {$exists:true}},
        [
            { $addFields: { 'posts.lastMod': new ISODate() } }
        ]
    );