update remove positional operator not array mongodb pymongo mongoengine

mongodb - positional - pymongo remove a field



MongoDB: Eliminar un campo de TODOS los subdocumentos en un campo de matriz (1)

Tengo miles de documentos en este formato:

{ "_id" : ObjectId("51e98d196b01c2085c72d731"), "messages" : [ { "_id" : ObjectId("520167056b01c20bb9eee987"), "id" : ObjectId("520167056b01c20bb9eee987"), }, { "_id" : ObjectId("520167056b01c20bb9eee988"), "id" : ObjectId("520167056b01c20bb9eee988"), }, { "_id" : ObjectId("520167056b01c20bb9eee989"), "id" : ObjectId("520167056b01c20bb9eee989"), } ], }

Necesito eliminar el campo duplicado "id". Esto es lo que he intentado:

db.forum_threads.update({}, {$unset: {"messages.$.id": 1}}, {multi: true});

Este es el error que estoy recibiendo:

Cannot apply the positional operator without a corresponding query field containing an array.


La razón por la que recibe ese error es porque no tiene ningún predicado en la cláusula de filtro. Puedes hacerlo:

mongos> db.test.update({"messages.id": {$exists: true}}, {$unset: {"messages.$.id":true}}, {multi:true})

Y no obtendrá un error; de hecho, uno de los documentos tendrá el atributo de id eliminado. El problema es que el operador de posición solo coincide con el PRIMER elemento de la matriz que coincide con su predicado, no coincide con todos los elementos. El problema más grande es que actualmente no es posible actualizar todos los elementos en una matriz en MongoDB ( https://jira.mongodb.org/browse/SERVER-1243 ).

Necesitarás iterar a través de cada elemento en la matriz usando la posición numérica ("messages.0.id", "messages.1.id", etc.) o puedes insertar la matriz en tu aplicación, recorrer el elementos y actualizarlos, y luego guardar la matriz de nuevo.

Puede ver en el boleto de JIRA que este problema ha estado abierto por un tiempo, pero 10gen no parece considerarlo de alta prioridad.