Страхувам се, че не е възможно с една атомна актуализация, ще трябва да направите няколко операции за актуализация, които отговарят и на двете условия.
Разбийте логиката за актуализиране на две отделни операции за актуализиране, като първата ще изисква използването на позиционен $
оператор
за идентифициране на елемента в history
масив, който искате, и $set
за актуализиране на съществуващите полета. Тази операция следва логиката актуализиране на полетата, АКО името И организацията съвпадат
Сега бихте искали да използвате findAndModify()
метод за тази операция, тъй като може да върне актуализирания документ. По подразбиране върнатият документ не включва промените, направени при актуализацията.
Така че, въоръжени с този арсенал, след това можете да изследвате втората си логика в следващата операция, т.е. актуализиране, АКО тази комбинация от "history.name" и "history.organisation" не съществува в масива . С тази операция за второ актуализиране ще трябва след това да използвате $push
оператор за добавяне на елементите.
Следващият пример демонстрира горната концепция. Първоначално се предполага, че имате частта за заявката и документа, които трябва да бъдат актуализирани като отделни обекти.
Да вземем например, когато имаме документи, които съответстват на съществуващия масив с история, той ще извърши само една операция за актуализиране, но ако документите не съвпадат, тогава findAndModify()
ще върне null, използвайте тази логика във втората си операция за актуализиране, за да изпратите документа към масива:
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 } }
);
}
След тази операция за документи, които съвпадат, запитването към колекцията ще даде същото
db.users.find({ "email": "[email protected]" });
Изход:
{
"_id" : ObjectId("575fe85bfe98c1fba0a6e535"),
"email" : "[email protected]",
"__v" : 0,
"history" : [
{
"name" : "Test123",
"organisation" : "Rat",
"field" : 4,
"another" : 3
}
]
}
Сега помислете за документи, които няма да съвпадат:
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 } }
);
}
Извършва се запитване към тази колекция за този документ
db.users.find({ "email": "[email protected]" });
ще даде
Изход:
{
"_id" : ObjectId("575fe85bfe98c1fba0a6e535"),
"email" : "[email protected]",
"__v" : 0,
"history" : [
{
"name" : "Test123",
"organisation" : "Rat",
"field" : 4,
"another" : 3
},
{
"name" : "foo",
"organisation" : "bar"
}
]
}