2011-03-08 24 views
31

tengo una estructura de documento algo en la línea de lo siguiente:Cómo eliminar un elemento de una matriz doblemente anidado en un documento MongoDB

{ 
"_id" : "777", 
"someKey" : "someValue", 
"someArray" : [ 
    { 
     "name" : "name1", 
     "someNestedArray" : [ 
      { 
       "name" : "value" 
      }, 
      { 
       "name" : "delete me" 
      } 
     ] 
    } 
    ] 
} 

que desea eliminar el elemento de la matriz anidada con el valor " borrame".

Sé que puedo encontrar documentos que coincidan con esta descripción utilizando expresiones $ elemMatch anidadas. ¿Cuál es la sintaxis de consulta para eliminar el elemento en cuestión?

Respuesta

31

Para eliminar el elemento en cuestión, en realidad va a utilizar una actualización. Más específicamente, vas a hacer una actualización con el comando $pull que eliminará el elemento de la matriz.

db.temp.update(
    { _id : "777" }, 
    {$pull : {"someArray.0.someNestedArray" : {"name":"delete me"}}} 
) 

Hay un poco de "magia" pasando aquí. El uso de .0 indica que sabemos que estamos modificando el 0 ° ítem de someArray. El uso de {"name":"delete me"} indica que conocemos los datos exactos que planeamos eliminar.

Este proceso funciona bien si carga los datos en un cliente y luego realiza la actualización. Este proceso funciona menos si quiere hacer consultas "genéricas" que realizan estas operaciones.

Creo que es más fácil simplemente reconocer que la actualización de matrices de sub documentos generalmente requiere que tenga el original en la memoria en algún momento.


En respuesta al primer comentario más abajo, es probable que pueda ayudar a su situación cambiando la estructura de datos un poco

"someObjects" : { 
    "name1": { 
     "someNestedArray" : [ 
      { 
       "name" : "value" 
      }, 
      { 
       "name" : "delete me" 
      } 
     ] 
    } 
} 

Ahora usted puede hacer {$pull : { "someObjects.name1.someNestedArray" : ...

Aquí está el problema con su estructura . MongoDB no tiene un soporte muy bueno para manipular "sub-arrays". Su estructura tiene una matriz de objetos y esos objetos contienen matrices de más objetos.

Si tienen la siguiente estructura, que va a tener dificultades para usar cosas como $pull:

array [ 
    { subarray : array [] }, 
    { subarray : array [] }, 
] 

Si la estructura se parece a la y desea actualizar subarray tiene dos opciones:

  1. Cambia tu estructura para que puedas aprovechar $pull.
  2. No utilice $pull. Cargue todo el objeto en un cliente y use findAndModify.
+4

¿Qué pasa si no sabemos el índice de la artículo en someArray? Debería haber especificado esa condición en mi pregunta original, mis disculpas. – rshepherd

+3

La forma en que especificó someObjects.name1 no parece funcionar? – Lion789

+2

Estoy luchando con este problema. MongoDB no es compatible con Deep 2nd '$' [operador posicional] para buscar y actualizar. –

2

Como se ha comentado @Melkor (probablemente debería ser una respuesta lo mismo),

Si no se conoce el uso de índice:

{_id: TheMainID, theArray._id: TheArrayID}, {$pull: {"theArray.$.theNestedArray": {_id: theNestedArrayID}}} 
Cuestiones relacionadas