Du kan inte referera till värdena för dokumentet du vill uppdatera, så du behöver en fråga för att hämta dokumentet och en annan för att uppdatera det. Det verkar som att det finns en funktionsbegäran
för det i OPEN
staten sedan 2016.
Om du har en samling med dokument som ser ut så här:
{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name" : "bar" }
Med MongoDB-skalet kan du göra något så här:
db.test.find({ name: "bar" }).snapshot().forEach((doc) => {
doc.name = "foo-" + doc.name;
db.test.save(doc);
});
Dokumentet kommer att uppdateras som förväntat:
{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name": "foo-bar" }
Observera .snapshot()
Detta säkerställer att frågan inte returnerar ett dokument flera gånger eftersom en mellanliggande skrivoperation flyttar det på grund av att dokumentstorleken ökar.
Att tillämpa detta på ditt Mongoose-exempel, som förklaras i detta officiella exempel :
Cat.findById(1, (err, cat) => {
if (err) return handleError(err);
cat.name = cat.name + "bar";
cat.save((err, updatedCat) => {
if (err) return handleError(err);
...
});
});
Det är värt att nämna att det finns en $concat
operatör i aggregeringsramverket, men tyvärr kan du inte använda det i en update
fråga.
Hur som helst, beroende på vad du behöver göra, kan du använda det tillsammans med $out
operatör för att spara resultaten av aggregeringen till en ny samling.
Med samma exempel kommer du att göra:
db.test.aggregate([{
$match: { name: "bar" }
}, {
$project: { name: { $concat: ["foo", "-", "$name"] }}
}, {
$out: "prefixedTest"
}]);
Och en ny samling prefixedTest
kommer att skapas med dokument som ser ut så här:
{ "_id" : ObjectId("XXX"), "name": "foo-bar" }
Bara som en referens finns det en annan intressant fråga om samma ämne med några svar värda att läsa:Uppdatera MongoDB-fältet med värdet från ett annat fält