At flad et array kan føre til ret store dokumenter, fordi for hvert indre array-element skal alle data fra dets ydre element gentages (og dette for alle niveauer).
Så hvis fladning ikke er en mulighed, er her en løsning, mens du venter på den forbedrede funktionalitet i den nævnte Jira (SERVER-831 ):
- læs dokumentet til en variabel
- manipuler arrayet
- opdater dokumentet ved at omskrive hele arrayet
Givet dine eksempler ville dette se sådan ud:
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 er:
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"
}
]
}
]
}
]
}