2012-09-27 17 views
10

tengo estos datos en Mongo:Actualizar un elemento en el sub de la matriz de sub en mongodb

{ 
    "_id" : ObjectId("505fd43fdbed3dd93f0ae088"), 
    "categoryName" : "Cat 1", 
    "services" : [ 
     { 
      "serviceName" : "Svc 1", 
      "input" : [ 
       { "quantity" : 10, "note" : "quantity = 10" }, 
       { "quantity" : 20, "note" : "quantity = 20" } 
      ] 
     }, 
     { 
      "serviceName" : "Svc 2", 
      "input" : [ 
       { "quantity" : 30, "note" : "quantity = 30" }, 
       { "quantity" : 40, "note" : "quantity = 40" } 
      ] 
     } 
    ] 
} 

Ahora quiero poner al día una cantidad de "Svc 1":

{ "quantity" : 10, "note" : "quantity = 10" } 

igual:

{"quantity": 100, "note": "changed to 100"} 

¿Cómo se puede hacer con Mongo? `

Como ya kno w, el operador operativo solo admite la primera matriz, alguien aconseja utilizar el índice de un elemento de la matriz sub sub, pero el problema es cómo saber ese índice en tiempo de ejecución. (Estoy usando el controlador nativo C# de MongoDB)

Gracias de antemano por sus ayuda!

Johnny

Respuesta

10

Dado que tiene una matriz dentro de un arreglo, no hay ninguna manera fácil de hacer referencia al subconjunto anidado menos que conozca la posición en la matriz que desea actualizar.

Así, por ejemplo, puede actualizar la primera entrada para 'Svc 1' con el equivalente C# de:

db.services.update(

    // Criteria 
    { 
     '_id' : ObjectId("505fd43fdbed3dd93f0ae088"), 
     'services.serviceName' : 'Svc 1' 
    }, 

    // Updates 
    { 
     $set : { 
      'services.$.input.0.quantity' : 100, 
      'services.$.input.0.note' : 'Quantity updated to 100' 
     } 
    } 
) 

Si no conoce la posición para el anidado input matriz, que tendrá para obtener el services correspondiente, itere la matriz input en el código de la aplicación, luego $set la matriz actualizada.

Alternativamente, podría modificar su matriz anidada utilizar un documento incrustado en su lugar, por ejemplo:

{ 
    "categoryName" : "Cat 1", 
    "services" : [ 
     { 
      "serviceName" : "Svc 1", 
      "input1" : { "quantity" : 10, "note" : "quantity = 10" }, 
      "input2" : { "quantity" : 20, "note" : "quantity = 20" } 
     }, 
    ] 
} 

que luego se podría actualizar por su nombre, por ejemplo input1:

db.services.update(

    // Criteria 
    { 
     '_id' : ObjectId("5063e80a275c457549de2362"), 
     'services.serviceName' : 'Svc 1' 
    }, 

    // Updates 
    { 
     $set : { 
      'services.$.input1.quantity' : 100, 
      'services.$.input1.note' : 'Quantity updated to 100' 
     } 
    } 
) 
+0

Hay es una solicitud relacionada [SERVER-267] (https://jira.mongodb.org/browse/SERVER-267) (compatibilidad con comodines parciales) en el rastreador de problemas de MongoDB. – Stennie

+0

¡Gracias por su ayuda, Stennie! Actualmente, agrupo matriz de entrada y salida en otra colección como una solución alternativa. – Johnny

5

Dado que usted don' Para saber la posición del valor que quería actualizar, primero inserte un nuevo valor con la información actualizada y luego elimine el valor que desea actualizar.

db.services.update(
    { 
    '_id' : ObjectId("505fd43fdbed3dd93f0ae088"), 
    'services.serviceName' : 'Svc 1' 
    }, 
    { 
    { $addToSet: { 'services.$.input' : "new sub-Doc" } 
    } 
) 

y luego retirar cuando la inserción es el éxito

db.services.update(
    { 
    '_id' : ObjectId("505fd43fdbed3dd93f0ae088"), 
    'services.serviceName' : 'Svc 1' 
    }, 
    { 
    { $pull: { 'services.$.input' : { "quantity" : 10, "note" : "quantity = 10" } } 
    } 
) 

Esto es útil cuando el índice no se conoce y documento debe tener sub-documentos que tienen misma clave como "entrada" en la post Update an element in sub of sub array in mongodb

+3

Esto fue útil. Ahora estoy volviendo a MySql. Gracias. – JSideris

Cuestiones relacionadas