Você só pode usar o
$
operador posicional para arrays de nível único. No seu caso, você tem um array aninhado (heros
é uma matriz, e dentro dela cada herói tem um spells
variedade). Se você conhece os índices dos arrays, pode usar índices explícitos ao fazer uma atualização, como:
> db.test.update({"heros.nickname":"test", "heros.spells.spell_id":1}, {$set:{"heros.0.spells.1.level":3}});