Du kan ikke henvise til værdierne for det dokument, du vil opdatere, så du skal bruge én forespørgsel for at hente dokumentet og en anden for at opdatere det. Det ser ud til, at der er en funktionsanmodning
for det i OPEN
stat siden 2016.
Hvis du har en samling med dokumenter, der ser sådan ud:
{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name" : "bar" }
Ved at bruge MongoDB-skallen kan du gøre noget som dette:
db.test.find({ name: "bar" }).snapshot().forEach((doc) => {
doc.name = "foo-" + doc.name;
db.test.save(doc);
});
Dokumentet vil blive opdateret som forventet:
{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name": "foo-bar" }
Bemærk .snapshot()
Dette sikrer, at forespørgslen ikke returnerer et dokument flere gange, fordi en mellemliggende skriveoperation flytter det på grund af væksten i dokumentstørrelsen.
Anvendelse af dette på dit Mongoose-eksempel, som forklaret i dette officielle eksempel :
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 er værd at nævne, at der er en $concat
operator i aggregeringsrammerne, men det kan du desværre ikke bruge i en update
forespørgsel.
Uanset hvad du skal gøre, kan du bruge det sammen med $out
operatør for at gemme resultaterne af sammenlægningen til en ny samling.
Med det samme eksempel vil du gøre:
db.test.aggregate([{
$match: { name: "bar" }
}, {
$project: { name: { $concat: ["foo", "-", "$name"] }}
}, {
$out: "prefixedTest"
}]);
Og en ny samling prefixedTest
vil blive oprettet med dokumenter, der ser ud som:
{ "_id" : ObjectId("XXX"), "name": "foo-bar" }
Bare som reference er der et andet interessant spørgsmål om det samme emne med et par svar, der er værd at læse:Opdater MongoDB-feltet ved hjælp af værdien af et andet felt