Sie können nicht auf die Werte des Dokuments verweisen, das Sie aktualisieren möchten, daher benötigen Sie eine Abfrage, um das Dokument abzurufen, und eine andere, um es zu aktualisieren. Es sieht so aus, als gäbe es eine Funktionsanfrage
dafür in OPEN
Zustand seit 2016.
Wenn Sie eine Sammlung mit Dokumenten haben, die wie folgt aussehen:
{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name" : "bar" }
Mit der MongoDB-Shell können Sie etwa Folgendes tun:
db.test.find({ name: "bar" }).snapshot().forEach((doc) => {
doc.name = "foo-" + doc.name;
db.test.save(doc);
});
Das Dokument wird wie erwartet aktualisiert:
{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name": "foo-bar" }
Beachten Sie den .snapshot()
call. Dadurch wird sichergestellt, dass die Abfrage ein Dokument nicht mehrmals zurückgibt, weil ein dazwischenliegender Schreibvorgang es aufgrund der zunehmenden Dokumentgröße verschiebt.
Wenden Sie dies auf Ihr Mongoose-Beispiel an, wie in diesem offiziellen Beispiel erklärt :
Cat.findById(1, (err, cat) => {
if (err) return handleError(err);
cat.name = cat.name + "bar";
cat.save((err, updatedCat) => {
if (err) return handleError(err);
...
});
});
Erwähnenswert ist, dass es einen $concat
gibt
Operator im Aggregation Framework, aber leider können Sie das nicht in einem update
verwenden Abfrage.
Wie auch immer, je nachdem, was Sie tun müssen, können Sie das zusammen mit dem $out
Operator, um die Ergebnisse der Aggregation in einer neuen Sammlung zu speichern.
Mit demselben Beispiel werden Sie Folgendes tun:
db.test.aggregate([{
$match: { name: "bar" }
}, {
$project: { name: { $concat: ["foo", "-", "$name"] }}
}, {
$out: "prefixedTest"
}]);
Und eine neue Sammlung prefixedTest
wird mit Dokumenten erstellt, die wie folgt aussehen:
{ "_id" : ObjectId("XXX"), "name": "foo-bar" }
Nur als Referenz gibt es zu diesem Thema noch eine weitere interessante Frage mit ein paar lesenswerten Antworten:MongoDB-Feld mit dem Wert eines anderen Felds aktualisieren