Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB: Updating subdocument

Tags:

mongodb

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?

like image 218
kheya Avatar asked Apr 13 '11 09:04

kheya


People also ask

How do I update an element in MongoDB?

You can use the updateOne() or updateMany() methods to add, update, or remove array elements based on the specified criteria. It is recommended to use the updateMany() method to update multiple arrays in a collection.

How do I update a nested array in MongoDB?

Update Nested Arrays in Conjunction with $[]The $[<identifier>] filtered positional operator, in conjunction with the $[] all positional operator, can be used to update nested arrays. The following updates the values that are greater than or equal to 8 in the nested grades.

How do you update an array object in MongoDB?

To perform an update on all embedded array elements of each document that matches your query, use the filtered positional operator $[<identifier>] . The filtered positional operator $[<identifier>] specifies the matching array elements in the update document.

How do I update an embedded file in MongoDB?

Update Documents in an ArrayThe positional $ operator facilitates updates to arrays that contain embedded documents. Use the positional $ operator to access the fields in the embedded documents with the dot notation on the $ operator.


2 Answers

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

like image 125
Andrei Andrushkevich Avatar answered Sep 28 '22 15:09

Andrei Andrushkevich


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.

like image 21
user2924017 Avatar answered Sep 28 '22 16:09

user2924017