Il motivo per cui ricevi quell'errore è perché non hai alcun predicato nella clausola del filtro. Puoi farlo:
mongos> db.test.update({"messages.id": {$exists: true}}, {$unset: {"messages.$.id":true}}, {multi:true})
E non riceverai alcun errore, infatti uno dei documenti avrà il id
attributo rimosso. Il problema è che l'operatore posizionale corrisponde solo al PRIMO elemento dell'array che corrisponde al tuo predicato, non corrisponde a tutti gli elementi. Il problema più grande è che al momento non è possibile aggiornare tutti gli elementi in un array in MongoDB (https ://jira.mongodb.org/browse/SERVER-1243
).
Dovrai scorrere ogni elemento nell'array usando la posizione numerica ("messages.0.id", "messages.1.id", ecc.) oppure puoi estrarre l'array nella tua applicazione, scorrere il elementi e aggiornali, quindi salva nuovamente l'array.
Puoi vedere dal ticket JIRA che questo problema è stato aperto per un po' di tempo, ma 10gen non sembra considerarlo una priorità molto alta.