16

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

1
  • Hi, If i want to update the above document with new values for genre like {name:'Sport', count:1} then how will I achieve it? Commented Sep 3, 2013 at 6:44

2 Answers 2

21

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>}})
Sign up to request clarification or add additional context in comments.

Comments

1

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!

1 Comment

What happens when the document can be updated concurrently? This will lead to a read-modify-write race condition no?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.