Obávám se, že to není možné s jedinou atomickou aktualizací. Obávám se, že byste museli provést několik aktualizačních operací, které splňují obě podmínky.
Rozdělte logiku aktualizace do dvou odlišných operací aktualizace, první by vyžadovala použití poziční $
operátor
k identifikaci prvku v history
požadované pole a $set
aktualizovat stávající pole. Tato operace se řídí logikou aktualizace polí, POKUD se název AND organizace shoduje
Nyní byste chtěli použít findAndModify()
metodu pro tuto operaci, protože může vrátit aktualizovaný dokument. Ve výchozím nastavení vrácený dokument neobsahuje úpravy provedené při aktualizaci.
Vyzbrojeni tímto arzenálem tedy můžete v další operaci prozkoumat svou druhou logiku, tj. aktualizovat, POKUD kombinace „history.name“ a „history.organisation“ v poli neexistuje . S touto operací druhé aktualizace byste pak museli použít $push
operátor pro přidání prvků.
Následující příklad demonstruje výše uvedený koncept. Zpočátku předpokládá, že máte část dotazu a dokument, které mají být aktualizovány, jako samostatné objekty.
Vezměme si například, když máme dokumenty, které odpovídají existujícímu poli historie, provede se pouze jedna operace aktualizace, ale pokud se dokumenty neshodují, pak findAndModify()
metoda vrátí null, použijte tuto logiku ve vaší druhé aktualizační operaci k odeslání dokumentu do pole:
var doc = {
"name": "Test123",
"organisation": "Rat"
}, // document to update. Note: the doc here matches the existing array
query = { "email": "[email protected]" }; // query document
query["history.name"] = doc.name; // create the update query
query["history.organisation"] = doc.organisation;
var update = db.users.findAndModify({
"query": query,
"update": {
"$set": {
"history.$.name": doc.name,
"history.$.organisation": doc.organisation
}
}
}); // return the document modified, if there's no matched document update = null
if (!update) {
db.users.update(
{ "email": query.email },
{ "$push": { "history": doc } }
);
}
Po této operaci pro dokumenty, které se shodují, dotazování kolekce přinese stejné
db.users.find({ "email": "[email protected]" });
Výstup:
{
"_id" : ObjectId("575fe85bfe98c1fba0a6e535"),
"email" : "[email protected]",
"__v" : 0,
"history" : [
{
"name" : "Test123",
"organisation" : "Rat",
"field" : 4,
"another" : 3
}
]
}
Nyní zvažte dokumenty, které se neshodují:
var doc = {
"name": "foo",
"organisation": "bar"
}, // document to update. Note: the doc here does not matches the current array
query = { "email": "[email protected]" }; // query document
query["history.name"] = doc.name; // create the update query
query["history.organisation"] = doc.organisation;
var update = db.users.findAndModify({
"query": query,
"update": {
"$set": {
"history.$.name": doc.name,
"history.$.organisation": doc.organisation
}
}
}); // return the document modified, if there's no matched document update = null
if (!update) {
db.users.update(
{ "email": query.email },
{ "$push": { "history": doc } }
);
}
Probíhá dotazování této kolekce na tento dokument
db.users.find({ "email": "[email protected]" });
by vynesl
Výstup:
{
"_id" : ObjectId("575fe85bfe98c1fba0a6e535"),
"email" : "[email protected]",
"__v" : 0,
"history" : [
{
"name" : "Test123",
"organisation" : "Rat",
"field" : 4,
"another" : 3
},
{
"name" : "foo",
"organisation" : "bar"
}
]
}