Не можете да се обърнете към стойностите на документа, който искате да актуализирате, така че ще ви трябва една заявка, за да извлечете документа, и друга, за да го актуализирате. Изглежда, че има заявка за функция
за това в OPEN
състояние от 2016 г.
Ако имате колекция с документи, които изглеждат така:
{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name" : "bar" }
Използвайки обвивката на MongoDB, можете да направите нещо подобно:
db.test.find({ name: "bar" }).snapshot().forEach((doc) => {
doc.name = "foo-" + doc.name;
db.test.save(doc);
});
Документът ще бъде актуализиран според очакванията:
{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name": "foo-bar" }
Обърнете внимание на .snapshot()
повикване. Това гарантира, че заявката няма да върне документ многократно, защото намесена операция за запис го премества поради нарастването на размера на документа.
Прилагане на това към вашия пример за Mongoose, както е обяснено в този официален пример :
Cat.findById(1, (err, cat) => {
if (err) return handleError(err);
cat.name = cat.name + "bar";
cat.save((err, updatedCat) => {
if (err) return handleError(err);
...
});
});
Струва си да се спомене, че има $concat
оператор в рамката за агрегиране, но за съжаление не можете да го използвате в update
заявка.
Както и да е, в зависимост от това, което трябва да направите, можете да го използвате заедно с $out
оператор за запазване на резултатите от агрегацията в нова колекция.
Със същия този пример ще направите:
db.test.aggregate([{
$match: { name: "bar" }
}, {
$project: { name: { $concat: ["foo", "-", "$name"] }}
}, {
$out: "prefixedTest"
}]);
И нова колекция prefixedTest
ще бъдат създадени с документи, които изглеждат така:
{ "_id" : ObjectId("XXX"), "name": "foo-bar" }
Само като справка, има друг интересен въпрос относно същата тема с няколко отговора, които си струва да прочетете:Актуализиране на MongoDB поле с помощта на стойност на друго поле