MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Aggiornamento simultaneo di elementi dell'array che sono documenti incorporati in MongoDB

Il processo qui è davvero abbastanza semplice, varia solo nel punto in cui vuoi "trovare o creare" gli elementi nell'array.

Innanzitutto, supponendo che gli elementi per ciascuna chiave siano già presenti, il caso semplice è interrogare l'elemento e aggiornarlo con l'indice restituito tramite posizionale $ operatore:

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

Ciò modificherà solo l'elemento corrispondente senza influire sugli altri.

Nel secondo caso in cui è richiesto "trova o crea" e la chiave particolare potrebbe non esistere, si utilizzano "due" istruzioni di aggiornamento. Ma l'API per le operazioni in blocco ti consente di farlo in un'unica richiesta al server con un'unica risposta:

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 logica di base è che prima viene effettuato il tentativo di aggiornamento per abbinare un elemento con i valori richiesti proprio come fatto prima. L'altra condizione verifica dove l'elemento non viene trovato affatto invertendo la logica di corrispondenza con $not .

Nel caso in cui l'elemento dell'array non sia stato trovato, uno nuovo è valido per l'aggiunta tramite $push .

Dovrei davvero aggiungere che poiché stiamo cercando specificamente corrispondenze negative qui, è sempre una buona idea abbinare il "documento" che intendi aggiornare con un identificatore univoco come _id chiave. Sebbene sia possibile con gli aggiornamenti "multipli", devi stare attento a ciò che stai facendo.

Quindi nel caso di esecuzione del processo "trova o crea" l'elemento che non è stato abbinato viene aggiunto correttamente all'array, senza interferire con altri elementi, anche l'aggiornamento precedente per una corrispondenza attesa viene applicato allo stesso modo:

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

Questo è uno schema semplice da seguire e, naturalmente, le operazioni in blocco qui rimuovono qualsiasi sovraccarico coinvolto inviando e ricevendo più richieste da e verso il server. Tutto questo fortunatamente funziona senza interferire con altri elementi che possono esistere o meno.

A parte questo, ci sono gli ulteriori vantaggi di mantenere i dati in un array per una facile query e analisi come supportato dagli operatori standard senza la necessità di ripristinare l'elaborazione del server JavaScript per attraversare gli elementi.