Aplatir un tableau peut conduire à des documents assez volumineux, car pour chaque élément interne du tableau, toutes les données de son élément externe doivent être répétées (et cela pour tous les niveaux).
Donc, si l'aplatissement n'est pas une option, voici une solution de contournement en attendant la fonctionnalité améliorée dans le Jira mentionné (SERVEUR-831 ):
- lire le document dans une variable
- manipuler le tableau
- mettre à jour le document, en réécrivant tout le tableau
D'après vos exemples, cela ressemblerait à ceci :
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}});
Le résultat est :
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"
}
]
}
]
}
]
}