2010-08-13 12 views
8

Estoy desarrollando una aplicación web que tiene un componente portal-ish (piense como múltiples paneles que pueden ser medicamentos de una columna a otra y agregados o eliminados). Estoy usando MongoDB para almacenar esta información con un formato como así ...

{ 
    _id: ObjectId(...), 
    title: 'My Layout', 
    columns: [ 
     { 
      order: 1, 
      width: 30, 
      panels: [ 
       { title: 'Panel Title', top: 100, content: '...' }, 
       { title: 'Panel Title', top: 250, content: '...' }, 
      ] 
     }, 
     { 
      ... multiple columns ... 
     } 
    ] 
} 

Estoy intentando utilizar operaciones/modificadoras atómicas con actualización() y esto se está volviendo confuso. Si quisiera actualizar solo una propiedad de un panel específico, ¿cómo hago referencia a eso?

update(
    { _id: ObjectId(...) }, 
    { $set: { columns.[???].panels.[???].top: 500 } 
) 

Respuesta

14

Si conoce el índice en la matriz, puede acceder directamente al elemento de matriz mediante la notación de puntos.

update(
{ _id: ObjectId(xxxx) }, 
{ $set: { 'columns.0.panels.0.top' : 125}} 
) 

Asegúrate de encajonar la ruta de puntos entre comillas como una cadena.

Editar:

Para dar más detalles sobre cómo esto podría funcionar de forma dinámica, voy a dar un ejemplo en PHP:

$action = array("columns.$colNum.panels.$panelNum" => $newValue); 

Sí existe la positional operator, pero does not appear to be advanced enough para cambiar matrices dentro de matrices, esto puede cambiar en MongoDB 1.7.0

Hay una alternativa que puede hacer en lugar de tratar de rellenar esta información en un documento anidado. Intenta aplanarlo. Se puede crear una colección que tiene panel de & objetos de columna:

columna de objeto:

{ 
_id: // MongoId 
type: 'column', 
user: 'username', 
order: 1, 
width: 30, 
} 

panel Objeto:

{ 
_id: //MongoId 
type: 'panel', 
user: 'username', 
parentColumn: //the columns _id string 
top: 125, 
left: 100 
} 

entonces usted puede encontrar todas las columnas que pertenecen a un usuario haciendo:

find({ type: 'column', user:'username'}); 

Puede encontrar todos los paneles para una columna específica haciendo:

find({type: 'panel', columnOwner:'ownerID'}); 

Dado que cada columna y el panel tendrán un identificador único dado por MongoDB a ella, se puede consultar fácilmente y las opciones de ajuste de forma atómica.

update({'_id': ObjectId('idstring')}, {$set : { 'top' : 125}}); 
+0

Me pregunto esto también. Hard-codificación de los índices realmente no es tan factible. Todavía tratando de descubrir cómo usar el operador posicional http://www.mongodb.org/display/DOCS/Updating#Updating-The%24positionaloperator – Dex

+0

agregó más detalles – Klinky

0

Yo también tuve una situación como esta, seguí $ addToSet después de $ pull para reemplazar, es decir, actualizar lo que necesitaba.

update(
{ _id: ObjectId(...) }, 
{ $addToSet: { columns.$.panels : "new sub-Doc" } 
) 

y luego retire el valor antiguo

update({_id:ObjectId(....)},{$pull : { columns.$.panels : {"top" : 100} }}) 
+0

¿Cuánto cuesta $ en las columnas? –

+0

"$" Actúa como un marcador de posición para actualizar el primer elemento que coincide con la condición de consulta en una actualización. por favor, consulte https: //docs.mongodb.com/manual/reference/operator/update/posicional/# up._S_ – achuth

Cuestiones relacionadas