Här är den stora frågan, behöver du utnyttja Mongos "addToSet" och "push" operationer? Om du verkligen planerar att bara modifiera enskilda objekt i arrayen, bör du förmodligen bygga dessa arrayer som objekt.
Så här skulle jag strukturera det här:
{
id: 1,
items:
{
"2" : { "blocks" : { "3" : { txt : 'hello' } } },
"5" : { "blocks" : { "1" : { txt : 'foo'}, "2" : { txt : 'bar'} } }
}
}
Detta omvandlar i princip allt till JSON-objekt istället för arrayer. Du förlorar möjligheten att använda $push
och $addToSet
men jag tror att det här gör allt lättare. Till exempel skulle din fråga se ut så här:
db.objects.update({'items.2':{$exists:true} }, {'$set':{'items.2.blocks.0.txt':'hej'}})
Du kommer också att märka att jag har dumpat "ID". När du kapslar saker som detta kan du i allmänhet ersätta "ID" med att helt enkelt använda det numret som ett index. "ID"-konceptet är nu underförstått.
Den här funktionen har lagts till i 3.6 med uttrycksfulla uppdateringar.
db.objects.update( {id:1 }, { $set:{ 'items.$[itm].blocks.$[blk].txt':"hej", } }, { multi:false, arrayFilters:[ { 'itm.id':2 }, { 'blk.id':3} ] } )