sql >> Databáze >  >> NoSQL >> MongoDB

Souběžná aktualizace prvků pole, které jsou vloženými dokumenty v MongoDB

Postup je zde opravdu docela jednoduchý, liší se pouze v tom, kde chcete "najít nebo vytvořit" prvky v poli.

Za prvé, za předpokladu, že prvky pro každý klíč jsou již na svém místě, pak jednoduchým případem je dotaz na prvek a aktualizaci pomocí indexu vráceného prostřednictvím poziční $ operátor:

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

Tím se změní pouze prvek, který se shoduje, aniž by to ovlivnilo ostatní.

Ve druhém případě, kdy je vyžadováno "najít nebo vytvořit" a konkrétní klíč nemusí existovat, použijete "dva" příkazy aktualizace. Ale Bulk Operations API umožňuje to provést v jediném požadavku na server s jedinou odpovědí:

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();

Základní logika spočívá v tom, že nejprve se provede pokus o aktualizaci, aby odpovídal prvku s požadovanými hodnotami stejně jako dříve. Další podmínka testuje, kde prvek nebyl vůbec nalezen, obrácením logiky shody pomocí $not .

V případě, že prvek pole nebyl nalezen, je platný nový prvek pro přidání prostřednictvím $push .

Opravdu bych měl dodat, že protože zde konkrétně hledáme negativní shody, je vždy dobré porovnat "dokument", který chcete aktualizovat, pomocí nějakého jedinečného identifikátoru, jako je _id klíč. I když je to možné s „více“ aktualizacemi, musíte si dávat pozor na to, co děláte.

Takže v případě spuštění procesu "najít nebo vytvořit" je prvek, který nebyl spárován, přidán do pole správně, bez zásahu do jiných prvků, stejným způsobem se použije také předchozí aktualizace pro očekávanou shodu:

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

Toto je jednoduchý vzor, ​​který je třeba dodržovat, a hromadné operace zde samozřejmě odstraňují veškerou režii související s odesíláním a přijímáním více požadavků na server a ze serveru. To vše šťastně funguje bez zasahování do jiných prvků, které mohou nebo nemusí existovat.

Kromě toho existují další výhody uchovávání dat v poli pro snadné dotazování a analýzu, jak je podporováno standardními operátory, aniž byste se museli vracet ke zpracování na serveru JavaScript za účelem procházení prvků.




  1. Důsledky použití $unwind na vnořených polích?

  2. Jak zvrátit uvolněnou agregaci?

  3. mongorestore se nezdaří kvůli neplatnému BSONSize

  4. Jak provedu dotaz v Mongoose?