O motivo pelo qual você está recebendo esse erro é porque você não tem nenhum predicado na cláusula de filtro. Você consegue fazer isso:
mongos> db.test.update({"messages.id": {$exists: true}}, {$unset: {"messages.$.id":true}}, {multi:true})
E você não receberá um erro - na verdade, um dos documentos terá o
id
atributo removido. O problema é que o operador posicional corresponde apenas ao PRIMEIRO elemento da matriz que corresponde ao seu predicado, não corresponde a todos os elementos. O maior problema é que atualmente não é possível atualizar todos os elementos em um array no MongoDB (https ://jira.mongodb.org/browse/SERVER-1243
). Você precisará percorrer cada elemento no array usando a posição numérica ("messages.0.id", "messages.1.id", etc.) elementos e atualizá-los e, em seguida, salve a matriz de volta.
Você pode ver no ticket do JIRA que esse problema está em aberto há algum tempo, mas a 10gen não parece considerá-lo uma prioridade muito alta.