2012-02-12 19 views
12

Tengo una colección con un esquema siguiente:actualizar mongodb el elemento específico de subarreglo

{ 
    "_id" : 28, 
    "n" : [{ 
     "a" : ObjectId("4ef8466e46b3b8140e000000"), 
     "c" : 28, 
     "p" : [ObjectId("4f00640646b3b88005000003"), ObjectId("4f00640146b3b88005000002"), ObjectId("4f00637d46b3b8cc0e000001"), ObjectId("4f00638046b3b8cc0e000002"), ObjectId("4f00638246b3b8cc0e000003"), ObjectId("4f00631646b3b85002000001"), ObjectId("4f00631846b3b85002000002")], 
     "u" : 26 
    }, { 
     "a" : ObjectId("4ef8466e46b3b8140e000000"), 
     "c" : 10, 
     "p" : [ObjectId("4f00640146b3b88005000002"), ObjectId("4f0063fd46b3b88005000001")], 
     "u" : 26 
    }, { 
     "a" : ObjectId("4ef8467846b3b8780d000001"), 
     "u" : 26, 
     "p" : [ObjectId("4f00637b46b3b8cc0e000000")], 
     "c" : 28 
    }, { 
     "a" : ObjectId("4ef85a3e46b3b84408000000"), 
     "u" : 26, 
     "p" : [ObjectId("4f00631046b3b85002000000")], 
     "c" : 28 
    }] 
} 

tengo que actualizar uno de los elementos de la matriz en el documento con _id = 28 pero sólo si la una = a algún valor yc = algún valor

db.coll.update({ 
'_id' : 28, 
'n.a' : new ObjectId('4ef85a3e46b3b84408000000'), 
'n.c' : 28 
}, 
{ 
    $push : { 
    'n.$.p' : ObjectId("4b97e62bf1d8c7152c9ccb74") 
    }, 
    $set : { 
    'n.$.t' : ISODate("2013-05-13T14:22:46.777Z") 
    } 
}) 

Así que básicamente quieren actualizar elemento específico de la matriz: y por lo que uno puede ver, este es el cuarto elemento. El problema es que cuando la consulta se está ejecutando, lo más probable es que actualice el primer elemento.

¿Cómo puedo repararlo?

Respuesta

23

El problema en su código es dot-notation porque cuando especifica la notación de punto, supone que los criterios de filtro especificados deben coincidir con el elemento de matriz única que cumple todos los criterios. Pero no es así. La notación de punto en las matrices puede recoger cualquier elemento de la matriz si coincide un solo criterio. Es por eso que recibes la actualización inesperada.

Tiene que usar $elemMatch para que coincida con todos los filtros en el elemento array.

db.coll.update({ 
'_id' : 28, 
n: { 
    $elemMatch:{ 
     a : new ObjectId('4ef85a3e46b3b84408000000'), 
     c : 28 } 
    } 
}, 
{ 
    $push : { 
    'n.$.p' : ObjectId("4b97e62bf1d8c7152c9ccb74") 
    }, 
    $set : { 
    'n.$.t' : ISODate("2013-05-13T14:22:46.777Z") 
    } 
}) 

y la salida es

{ 
     "a" : ObjectId("4ef85a3e46b3b84408000000"), 
     "c" : 28, 
     "p" : [ 
      ObjectId("4f00631046b3b85002000000"), 
      ObjectId("4b97e62bf1d8c7152c9ccb74") 
     ], 
     "t" : ISODate("2013-05-13T14:22:46.777Z"), 
     "u" : 26 
    } 
Cuestiones relacionadas