Update a nested array of a record in mongodb collection
Let's say you want to dynamically update an element of an array which belong to a certain collection. So basically you have some model which looks like :
Collection.name = {
somestring:'some name',
anArray:[]
}
Reading the docs here :
http://docs.mongodb.org/manual/reference/method/db.collection.update/#update-an-element-by-position and there : http://docs.mongodb.org/manual/reference/operator/update/positional/ or here :
You can get pretty neat information. Unfortunately when using some libs like mongoose or frameworks like meteorjs you can struggle with the fact that you have a dynamic field for the array index and the dot notation fails. So instead of this simple line of code :
db.bios.update(
{ _id: 1 },
{ $set: { "contribs.1": "ALGOL 58" } }
)
You end up with nothing :)
Who comes to the rescue, the object creation !
The idea is to simply create the object setter
to update the collection. So instead of writting in plain { "contribs.1": "ALGOL 58" }
you will prefer to write down :
var setter = {};
setter['contribs.1'] = 'ALGOL 58';
db.bios.update(
{ _id: 1 },
{ $set: setter}
)
Thus you can rewirte it withe the value from some param :
var setter = {};
setter['contribs'+req.index] = 'ALGOL 58';
db.bios.update(
{ _id: 1 },
{ $set: setter}
)
And voilà it works ! Enjoy !
Written by Gabriel
Related protips
1 Response
Another good way is to write your query as an $elemMatch and then update the matched record. This will become something like contribs.$.fieldtoupdate to point to the matched element. This is useful when dealing with an array of objects where elemMatch needs to match an embedded field.
This is also annoying when using say morphia, that tries very had to not let you do complex queries like this so that it can keep its object model properly. Its possible but you have to use its funky syntax.