Spłaszczenie tablicy może prowadzić do dość dużych dokumentów, ponieważ dla każdego wewnętrznego elementu tablicy wszystkie dane jego zewnętrznego elementu muszą zostać powtórzone (i to dla wszystkich poziomów).
Tak więc, jeśli flatten nie jest opcją, oto obejście podczas oczekiwania na ulepszoną funkcjonalność we wspomnianym Jira (SERWER-831 ):
- odczytaj dokument do zmiennej
- manipulować tablicą
- zaktualizuj dokument, przepisując całą tablicę
Biorąc pod uwagę twoje przykłady, wyglądałoby to tak:
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}});
Wynik:
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"
}
]
}
]
}
]
}