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ů.