sql >> Base de Datos >  >> NoSQL >> MongoDB

Actualización simultánea de elementos de matriz que son documentos incrustados en MongoDB

El proceso aquí es bastante simple, solo varía en el lugar donde desea "encontrar o crear" los elementos en la matriz.

Primero, asumiendo que los elementos para cada clave ya están en su lugar, entonces el caso simple es consultar el elemento y actualizar con el índice devuelto a través de posicional $ operador:

db.collection.update(
   {
       "_id": docId, 
       "attrs": { "$elemMatch": { "key": "A1", "type": "T1" } }
   }
   { "$set": { "attrs.$.value": "20" }
)

Eso solo modificará el elemento que coincida sin afectar a los demás.

En el segundo caso donde se requiere "buscar o crear" y la clave particular puede no existir, entonces usa "dos" declaraciones de actualización. Pero la API de operaciones masivas le permite hacer esto en una sola solicitud al servidor con una sola respuesta:

var bulk = db.collection.initializeOrderedBulkOp();

// Try to update where exists
bulk.find({
    "_id": docId,
    "attrs": { "$elemMatch": { "key": "A1", "type": "T2" } }
}).updateOne({
    "$set": { "attrs.$.value": "30" }
});

// Try to add where does noes not exist
bulk.find({
    "_id": docId,
    "attrs": { "$not": { "$elemMatch": { "key": "A1", "type": "T2" } } }
}).updateOne({
    "$push": { "attrs": { "key": "A1", "type": "T2", "value": "30" } }
});

bulk.execute();

La lógica básica es que primero se realiza el intento de actualización para hacer coincidir un elemento con los valores requeridos tal como se hizo antes. La otra condición comprueba dónde no se encuentra el elemento invirtiendo la lógica de coincidencia con $not .

En el caso de que no se haya encontrado el elemento de la matriz, se puede agregar uno nuevo a través de $push .

Realmente debería agregar que, dado que estamos buscando específicamente coincidencias negativas aquí, siempre es una buena idea hacer coincidir el "documento" que pretende actualizar con algún identificador único como el _id llave. Si bien es posible con actualizaciones "múltiples", debe tener cuidado con lo que está haciendo.

Entonces, en el caso de ejecutar el proceso "buscar o crear", el elemento que no coincidió se agrega a la matriz correctamente, sin interferir con otros elementos, también se aplica la actualización anterior para una coincidencia esperada de la misma manera:

{
    "_id" : ObjectId("55b570f339db998cde23369d"),
    "attrs" : [
            {
                    "key" : "A1",
                    "type" : "T1",
                    "value" : "20"
            },
            {
                    "key" : "A2",
                    "type" : "T2",
                    "value" : "14"
            },
            {
                    "key" : "A1",
                    "type" : "T2",
                    "value" : "30"
            }
    ]
}

Este es un patrón simple de seguir y, por supuesto, las operaciones masivas aquí eliminan cualquier sobrecarga involucrada al enviar y recibir múltiples solicitudes hacia y desde el servidor. Todo esto funciona felizmente sin interferir con otros elementos que pueden o no existir.

Aparte de eso, existen los beneficios adicionales de mantener los datos en una matriz para facilitar la consulta y el análisis con el soporte de los operadores estándar sin la necesidad de volver al procesamiento del servidor de JavaScript para recorrer los elementos.