Updating nested arrays in mongoDB via mongo shell [duplicate]

Following is a MongoDB document:

{
    "_id" : 2,
    "mem_id" : M002,
    "email" : "[email protected]",
    "event_type" : [ 
        {
            "name" : "MT",
            "count" : 1,
            "language" : [ 
                {
                    "name" : "English",
                    "count" : 1,
                    "genre" : [ 
                        {
                            "name" : "Action",
                            "count" : 6
                        }, 
                        {
                            "name" : "Sci-Fi",
                            "count" : 3
                        }
                    ],
                    "cast" : [ 
                        {
                            "name" : "Sam Wortington",
                            "count" : 2
                        }, 
                        {
                            "name" : "Bruce Willis",
                            "count" : 4
                        }, 
                        {
                            "name" : "Will Smith",
                            "count" : 7
                        }, 
                        {
                            "name" : "Irfan Khan",
                            "count" : 1
                        }
                    ]
                }
            ]
        }
    ]
}

I'm not able to update fields that is of type array, specially event_type, language, genre and cast because of nesting. Basically, I wanted to update all the four mentioned fields along with count field for each and subdocuments. The update statement should insert a value to the tree if the value is new else should increment the count for that value.
What can be the query in mongo shell? Thanks


You are directly hitting one of the current limitations of MongoDB. The problem is that the engine does not support several positional operators. See this Multiple use of the positional `$` operator to update nested arrays

There is an open ticket for this: https://jira.mongodb.org/browse/SERVER-831 (mentioned also there)

You can also read this one on how to change your data model: Updating nested arrays in mongodb

If it is feasible for you, you can do:

db.collection.update({_id:2,"event_type.name":'MT' ,"event_type.language.name":'English'},{$set:{"event_type.0.language.$.count":<number>}})

db.collection.update({_id:2,"event_type.name":'MT' ,"event_type.language.name":'English'},{$set:{"event_type.$.language.0.count":<number>}})

But you cannot do:

db.collection.update({_id:2,"event_type.name":'MT' ,"event_type.language.name":'English'},{$set:{"event_type.$.language.$.count":<number>}})

Let's take case by case:

  1. To update the field name in event_type array:

    db.testnested.update({"event_type.name" : "MT"}, {$set : {"event_type.name" : "GMT"}})

This command will update the name for an object inside the event_type list, to GMT from MT:

BEFORE:
db.testnested.find({}, {"event_type.name" : 1})
{ "_id" : 2, "event_type" : [ { "name" : "MT" } ] }
AFTER:
db.testnested.find({}, {"event_type.name" : 1})
{ "_id" : 2, "event_type" : [ { "name" : "GMT" } ] }

2.To update fields inside event_type, such as language, genre that are intern list: There is no direct query for this. You need to read the document, update that document using the JavaScript or language of your choice, and then save() the same. I dont think there is any other way available till mongo 2.4

For further documentation, you can refer to save().

Thanks!