Aqui está a grande questão, você precisa aproveitar as operações "addToSet" e "push" do Mongo? Se você realmente planeja modificar apenas itens individuais na matriz, provavelmente deve construir essas matrizes como objetos.
Veja como eu estruturaria isso:
{
id: 1,
items:
{
"2" : { "blocks" : { "3" : { txt : 'hello' } } },
"5" : { "blocks" : { "1" : { txt : 'foo'}, "2" : { txt : 'bar'} } }
}
}
Isso basicamente transforma tudo em objetos JSON em vez de matrizes. Você perde a capacidade de usar
$push
e $addToSet
mas acho que isso facilita tudo. Por exemplo, sua consulta ficaria assim:db.objects.update({'items.2':{$exists:true} }, {'$set':{'items.2.blocks.0.txt':'hi'}})
Você também notará que descartei os "IDs". Quando você está aninhando coisas assim, geralmente pode substituir "ID" simplesmente usando esse número como um índice. O conceito de "ID" agora está implícito.
Este recurso foi adicionado na versão 3.6 com atualizações expressivas.
db.objects.update( {id:1 }, { $set:{ 'items.$[itm].blocks.$[blk].txt':"hi", } }, { multi:false, arrayFilters:[ { 'itm.id':2 }, { 'blk.id':3} ] } )