Att platta ut en array kan leda till ganska stora dokument, eftersom för varje inre array-element måste all data från dess yttre element upprepas (och detta för alla nivåer).
Så om plattning inte är ett alternativ, här är en lösning medan du väntar på den förbättrade funktionen i nämnda Jira (SERVER-831 ):
- läs dokumentet till en variabel
- manipulera arrayen
- uppdatera dokumentet och skriv om hela arrayen
Med dina exempel skulle detta se ut så här:
doc = db.xx.findOne( {_id:1} );
doc.properties.forEach( function(p) {
if ( p.property_id == 2 ) {
p.tags.forEach( function(t) {
if ( t.tag_id == 3 ) {
t.tag_value = 100;
}
else if ( t.tag_id == 4 ) {
newChannel = {};
newChannel.channel_id = 5;
newChannel.channel_name = "test5";
t.channels.push(newChannel);
}
})
}
});
db.xx.update({_id:1},{$set:{properties:doc.properties}});
Resultatet är:
doc = db.xx.findOne({_id:1})
{
"_id" : 1,
"properties" : [
{
"property_id" : 1,
"tags" : [
{
"tag_id" : 1,
"tag_value" : 1000,
"channels" : [
{
"channel_id" : 1,
"channel_name" : "test1"
},
{
"channel_id" : 2,
"channel_name" : "test2"
}
]
},
{
"tag_id" : 2,
"tag_value" : 2500,
"channels" : [
{
"channel_id" : 2,
"channel_name" : "test2"
},
{
"channel_id" : 3,
"channel_name" : "test3"
}
]
}
]
},
{
"property_id" : 2,
"tags" : [
{
"tag_id" : 3,
"tag_value" : 100,
"channels" : [
{
"channel_id" : 1,
"channel_name" : "test1"
},
{
"channel_id" : 3,
"channel_name" : "test3"
}
]
},
{
"tag_id" : 4,
"tag_value" : 5000,
"channels" : [
{
"channel_id" : 1,
"channel_name" : "test1"
},
{
"channel_id" : 5,
"channel_name" : "test5"
}
]
}
]
}
]
}