2012-05-22 17 views
7

Tengo una estructura de objetos de esta manera: Modificar el último elemento de una matriz

{ 
    name: "...", 
    pockets: [ 
     { 
      cdate: "....", 
      items: [...] 
     } 
     ... 
    ] 
} 

En una operación de actualización, quiero agregar algunos registros en los artículos campo de la última bolsillo artículo. Usar notación de puntos es la única forma que conozco para acceder a un documento secundario, pero no puedo obtener lo que quiero. Por lo tanto, estoy buscando algo como esto:

  • pockets.-1.items
  • pockets.$last.items

¿Es posible modificar el último elemento? Si es así, ¿cómo?

+0

¿Estoy correcto de que quiera modificar 'items', no buscarlo? – paulmelnikow

+0

Sí, estás en lo correcto. En la búsqueda, puedo usar el operador $ slice. – Muatik

+0

Estoy bastante seguro de que esto no se puede hacer con una simple actualización a menos que tenga otra forma de unir el último bolsillo. – paulmelnikow

Respuesta

2

No conozco una forma de hacerlo con una consulta de una sola línea. Pero puede seleccionar el registro, actualizar y luego guardarlo.

var query = <insert query here>; 
var mydocs = db.mycollection.find(query); 
for (var i=0 ; i<mydocs.length ; i++) { 
    mydocs[i].pockets[pockets.length-1].items.push('new item'); 
    db.mycollection.save(mydoc); 
} 
+3

esto puede no ser seguro para subprocesos, ya que otro proceso podría haber modificado la matriz después del hallazgo y antes del guardado. –

+0

@AsyaKamsky punto excelente ... Actualizaré mi respuesta. – McGarnagle

2

No creo que sea posible hacerlo atómicamente. Hay un request para que esta funcionalidad se agregue a MongoDB.

Si usted puede asegurar hilo de seguridad en el código aplicación, que probablemente podría utilizar una secuencia de $ pop de los bolsillos array (que elimina el último elemento de bolsillos) a la variable p y luego $ addToSet a p.items , ahora puedes $ push p en los bolsillos. Pero si su aplicación no tiene una forma de asegurar que solo un proceso puede estar haciendo esto al mismo tiempo, entonces otro proceso podría modificar el arreglo en el medio de esos pasos y puede terminar perdiendo esa actualización.

También puede consultar la semántica "Actualizar si es actual" here para ver otra forma en que puede evitar la posible cuestión de raza por varios hilos.

Cuestiones relacionadas