Ikke muligt med en enkelt atomopdatering, er jeg bange for, at du skulle udføre et par opdateringsoperationer, der opfylder begge betingelser.
Opdel opdateringslogikken i to adskilte opdateringsoperationer, den første kræver brug af positionelle $
operatør
for at identificere elementet i history
array, du ønsker og $set
for at opdatere de eksisterende felter. Denne handling følger logikken opdateringsfelter, HVIS navnet OG organisationen matcher
Nu vil du gerne bruge findAndModify()
metode til denne handling, da den kan returnere det opdaterede dokument. Som standard inkluderer det returnerede dokument ikke de ændringer, der er foretaget på opdateringen.
Så, bevæbnet med dette arsenal, kan du derefter undersøge din anden logik i den næste operation, dvs. opdater, HVIS denne kombination af "history.name" og "history.organisation" ikke findes i arrayet em> . Med denne anden opdateringsoperation skal du derefter bruge $push
operatør for at tilføje elementerne.
Det følgende eksempel demonstrerer ovenstående koncept. Det forudsætter i første omgang, at du har forespørgselsdelen og dokumentet, der skal opdateres, som separate objekter.
Tag for eksempel, når vi har dokumenter, der matcher det eksisterende historikarray, vil det kun udføre en enkelt opdateringsoperation, men hvis dokumenterne ikke stemmer overens, så findAndModify()
metoden returnerer null, brug denne logik i din anden opdateringsoperation til at skubbe dokumentet til arrayet:
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 } }
);
}
Efter denne handling for dokumenter, der matcher, vil forespørgsel i samlingen give det samme
db.users.find({ "email": "[email protected]" });
Output:
{
"_id" : ObjectId("575fe85bfe98c1fba0a6e535"),
"email" : "[email protected]",
"__v" : 0,
"history" : [
{
"name" : "Test123",
"organisation" : "Rat",
"field" : 4,
"another" : 3
}
]
}
Overvej nu dokumenter, der ikke matcher:
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 } }
);
}
Forespørger på denne samling for dette dokument
db.users.find({ "email": "[email protected]" });
ville give sig
Output:
{
"_id" : ObjectId("575fe85bfe98c1fba0a6e535"),
"email" : "[email protected]",
"__v" : 0,
"history" : [
{
"name" : "Test123",
"organisation" : "Rat",
"field" : 4,
"another" : 3
},
{
"name" : "foo",
"organisation" : "bar"
}
]
}