Search code examples
mongodbshellfindandmodify

Yet another MongoDB findAndModify


Please consider the following document, a part of the Runtime collection:

{
"entity_id" : 10,
"features" : [ 
    {
        "10" : "Test System 2"
    }, 
    {
        "20" : "System 2 Description"
    }, 
    {
        "180" : ISODate("2013-12-25T18:19:40.589Z")
    }, 
    {
        "190" : ISODate("2013-12-25T18:19:40.589Z")
    }
],
"_id" : ObjectId("52bb21bc8a2ebdc01c000001")
}

My goal is to update the value of the element of the "features" array having the key "20". Here are the things I've tried (in mongo shell):

db.Runtime.findAndModify({ "query" : {"_id": "52bb21bc8a2ebdc01c000001"}, "update" : {$set      : {"features.$.20":"Updated Description"}}} );

db.Runtime.findAndModify({ "query" : {"_id": "52bb21bc8a2ebdc01c000001"}, "update" : {$set : {"features['20']":"Updated Description"}}} );

db.Runtime.findAndModify({ "query" : {"_id": "52bb21bc8a2ebdc01c000001"}, "update" : {$set : {"features[1]":"Updated Description"}}} );

In all instances the shell prints null and nothing happens to the data. So, the main question is, of course, what is wrong with my code snippets. Also, how that "null" is supposed to get interpreted? And is there such a thing as mongo shell's log where one could find any clues? Many thanks for your help!


Solution

  • When using the $ positional operator in an update, your query needs to include a term that matches the element of the array you're updating:

    db.Runtime.findAndModify({
        query: {_id: ObjectId("52bb21bc8a2ebdc01c000001"), 
                'features.20': {$exists: true}}, 
        update: {$set: {"features.$.20":"Updated Description"}}
    })
    

    Note that you also need to call ObjectId on your _id string to turn it into an actual ObjectId or it won't match the doc.