MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

So aktualisieren Sie ein Feld mit seinem vorherigen Wert in MongoDB/Mongoose

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