Ecco la grande domanda, è necessario sfruttare le operazioni "addToSet" e "push" di Mongo? Se hai davvero intenzione di modificare solo singoli elementi nell'array, dovresti probabilmente creare questi array come oggetti.
Ecco come lo strutturerei:
{
id: 1,
items:
{
"2" : { "blocks" : { "3" : { txt : 'hello' } } },
"5" : { "blocks" : { "1" : { txt : 'foo'}, "2" : { txt : 'bar'} } }
}
}
Questo fondamentalmente trasforma tutto in oggetti JSON anziché in array. Perdi la possibilità di usare $push
e $addToSet
ma penso che questo renda tutto più facile. Ad esempio, la tua query sarebbe simile a questa:
db.objects.update({'items.2': {$exists:true} }, {'$set': {'items.2.blocks.0.txt': 'hi'}})
Noterai anche che ho scaricato gli "ID". Quando stai annidando cose come questa, puoi generalmente sostituire "ID" semplicemente usando quel numero come indice. Il concetto di "ID" è ora implicito.
Questa funzionalità è stata aggiunta in 3.6 con aggiornamenti espressivi.
db.objects.update( {id: 1 }, { $set: { 'items.$[itm].blocks.$[blk].txt': "hi", } }, { multi: false, arrayFilters: [ { 'itm.id': 2 }, { 'blk.id': 3} ] } )