Elimina un campo de todos los elementos de la matriz en mongodb

Tengo el siguiente documento en MongoDB (2.4.5)

{ "_id" : 235399, "casts" : { "crew" : [ { "_id" : 1186343, "withBase" : true, "department" : "Directing", "job" : "Director", "name" : "Connie Rasinski" }, { "_id" : 86342, "withBase" : true } ] }, "likes" : 0, "rating" : 0, "rating_count" : 0, "release_date" : "1955-11-11" } 

Quiero eliminar withBase archivado desde los elementos del array dentro de castts.crew ..

Intenté esto

 db.coll.update({_id:235399},{$unset: { "casts.crew.withBase" : 1 } },false,true) 

nada ha cambiado.

Y lo intenté …

 db.coll.update({_id:235399},{$unset: { "casts.crew" : { $elemMatch: { "withBase": 1 } } } },false,true) 

eliminó todo el conjunto de tripulación del documento.

¿Alguien puede darme la consulta correcta?

Lamento decepcionarte, pero tu respuesta

 db.coll.update({ _id:235399, "casts.crew.withBase": {$exists: true} },{ $unset: { "casts.crew.$.withBase" : true } },false,true) 

no es correcto. En realidad, eliminará el valor, PERO solo desde la primera aparición del subdocumento, debido a la forma en que funciona el operador posicional :

el operador $ posicional actúa como un marcador de posición para el primer elemento que coincide con el documento de consulta

Tampoco puede usar $unset (como lo intentó anteriormente) porque no puede funcionar en matrices (y básicamente está tratando de eliminar una clave de un documento de la matriz). Tampoco puede eliminarlo con $pull , porque pull elimina toda la matriz, no solo un campo de la misma.

Por lo tanto, que yo sepa, no se puede hacer esto con un simple operador. Entonces, el último recurso es $find y luego forEach con save. Puedes ver cómo hacer esto en mi respuesta aquí . En su caso, debe tener otro bucle para forEach función para iterar a través de una matriz y eliminar una clave . Espero que puedas modificarlo. Si no, intentaré ayudarte.

PD: si alguien busca la manera de hacerlo, aquí está la función de Sandra

 db.coll.find({_id:235399}).forEach( function(doc) { var arr = doc.casts.crew; var length = arr.length; for (var i = 0; i < length; i++) { delete arr[i]["withBase"]; } db.coll.save(doc); }); 

Puede usar el nuevo positional identifier para actualizar múltiples elementos en una matriz en 3.6.

Algo como

  db.coll.update( {_id:235399}, {$unset: {"casts.crew.$[].withBase":""}} ) 

$ [] elimina toda la propiedad withBase de la matriz de crews . Actúa como un marcador de posición para actualizar todos los elementos en el conjunto.

Use multi verdadero para afectar documentos múltiples.

Encontré una manera de desarmar esta lista sin tener que levantar el objeto (es decir, simplemente haciendo una actualización), es bastante hackish pero si tienes una gran base de datos, hará el trato:

 db.coll.update({},{$unset: {"casts.crew.0.withBase" : 1, "casts.crew.1.withBase" : 1} }, {multi: 1}) 

En otras palabras, debe calcular cuántos objetos puede haber en su lista de documentos y agregar esos números explícitamente, en este caso como {casts.crew.NUMBER.withBase: 1} .

Además, para contar la matriz más larga en un objeto mongodb, se puede hacer un agregado, algo como esto:

 db.coll.aggregate( [ { $unwind : "$casts.crew" }, { $group : { _id : "$_id", len : { $sum : 1 } } }, { $sort : { len : -1 } }, { $limit : 1 } ], {allowDiskUse: true} ) 

Solo quiero enfatizar que esta no es una solución bonita, pero es mucho más rápido que buscar y guardar.