Reputation: 1714
I am rather new to mongodb and self learning. Since recently I am a bit stuck on this one. I would like to update a nested document. I worked around it by retrieving the full document and updating the entire thing, but I need a solution where I can update in a single shot. I made the following simplified example:
db.test.insert({
'name': 'someSchool',
'classes': [
{
'name': 'someClass',
'students': [
{
'name': 'Jack',
'coolness' : 7
}
]
}
]
});
Here the arrays only have one entry for simplicity, you understand we normally have more...
db.test.find({
'name' : 'someSchool',
'classes' : {
$elemMatch: {
'name': 'someClass',
'students.name' : 'Jack'
}
}
});
This find works! Thats great, so now I want to use it in an update, which is where Im stuck. Something like this??
db.test.update({
'name' : 'someSchool',
'classes' : {
$elemMatch: {
'name': 'someClass',
'students.name' : 'Jack'
}
}
}, {
'$set' : { 'classes.students.coolness' : 9}
});
So this doesnt work and now I am stuck at it :) Hopefully someone here can help.
Side note: I am using mongoose. If you guys tell me its better to change the schema to make it easier somehow, I can.
Update since marked as duplicate: In the referenced question, there is only 1 level of nesting and the problem gets solved by using dot notation. Here there are 2 levels. I accepted teh answer which explains it is not supported and which gives a correct workaround.
Upvotes: 1
Views: 6448
Reputation: 4055
As mentioned here it's not possible right now to update two level nested arrays.
I would suggest you to change your schema in order to replace one level array nesting with object. So your document would look like this:
{
"name" : "someSchool",
"classes" : {
"someClass" : {
"students" : [
{
"name" : "Jack",
"coolness" : 7
}
]
}
}
}
Then you can use positional operator to update specific array element. But be aware that positional operator updates only the first element in array that matches the query.
Update query would look like this:
db.test.update({
'classes.someClass.students' : {
$elemMatch: {
'name' : 'Jack'
}
}
}, {
'$set' : {
'classes.someClass.students.$.coolness' : 9
}
});
Upvotes: 1