MongoDB: Updating subdocument

Mongodb

Mongodb Problem Overview


I have this collection:

[{ "_id" : 7,   "category" : "Festival",   "comments" : [        {                "_id" : ObjectId("4da4e7d1590295d4eb81c0c7"),                "usr" : "Mila",                "txt" : "This is a comment",                "date" : "4/12/11"        }    ]
}]

All I want is to push insert a new field inside comments like this:

[{ "_id" : 7,
   "category" : "Festival",
   "comments" : [
        {
                "_id" : ObjectId("4da4e7d1590295d4eb81c0c7"),
                "usr" : "Mila",
                "txt" : "This is a comment",
                "date" : "4/12/11",
                "type": "abc"  // find the parent doc with id=7 & insert this inside comments
        }
    ]
}]

How can I insert inside the comments subdocument?

Mongodb Solutions


Solution 1 - Mongodb

You need to use the $ positional operator

For example:

update({ 
       _id: 7, 
       "comments._id": ObjectId("4da4e7d1590295d4eb81c0c7")
   },{
       $set: {"comments.$.type": abc}
   }, false, true
);

I didn't test it but i hope that it will be helpful for you.

If you want to change the structure of document you need to use

> db.collection.update( criteria, > objNew, upsert, multi ) > > Arguments: > > criteria - query which selects the record to update; > objNew - updated object or $ operators (e.g., $inc) which manipulate the object > upsert - if this should be an "upsert"; that is, if the record does not exist, nsert it > multi - if all documents matching criteria should be updated

and insert new objNew with new structure. check this for more details

Solution 2 - Mongodb

The $ positional operator is only going to work as expected if the 'comments' field is NOT an array. The OP's json is malformed, but it looks like it could be an array.

The issue is that mongodb right now will only update the first element of an array which matches the query. Though there is an RFE open to add support for updating all matching array elements: https://jira.mongodb.org/browse/SERVER-1243

To work around this issue with arrays you just have to do a regular find then update the elements in the array individually.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionkheyaView Question on Stackoverflow
Solution 1 - MongodbAndrei AndrushkevichView Answer on Stackoverflow
Solution 2 - Mongodbuser2924017View Answer on Stackoverflow