sql >> Databáze >  >> NoSQL >> MongoDB

Jak aktualizovat pole pomocí jeho předchozí hodnoty v MongoDB/Mongoose

Nemůžete odkazovat na hodnoty dokumentu, který chcete aktualizovat, takže budete potřebovat jeden dotaz k načtení dokumentu a další k jeho aktualizaci. Zdá se, že existuje žádost o funkci pro to v OPEN stavu od roku 2016.

Pokud máte sbírku s dokumenty, které vypadají takto:

{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name" : "bar" }

Pomocí shellu MongoDB můžete udělat něco takového:

db.test.find({ name: "bar" }).snapshot().forEach((doc) => {
    doc.name = "foo-" + doc.name;

    db.test.save(doc);
});

Dokument bude aktualizován podle očekávání:

{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name": "foo-bar" }

Všimněte si .snapshot() call.To zajistí, že dotaz nevrátí dokument vícekrát, protože probíhající operace zápisu jej přesune kvůli nárůstu velikosti dokumentu.

Aplikujte to na svůj příklad Mongoose, jak je vysvětleno v tomto oficiálním příkladu :

Cat.findById(1, (err, cat) => {
    if (err) return handleError(err);

    cat.name = cat.name + "bar";

    cat.save((err, updatedCat) => {
        if (err) return handleError(err);

        ...
    });
});

Stojí za zmínku, že existuje $concat operátor v agregačním rámci, ale bohužel jej nemůžete použít v update dotaz.

Každopádně, v závislosti na tom, co potřebujete udělat, to můžete použít spolu s $out operátora k uložení výsledků agregace do nové kolekce.

Se stejným příkladem uděláte:

db.test.aggregate([{
    $match: { name: "bar" }
}, {
    $project: { name: { $concat: ["foo", "-", "$name"] }}
}, {
    $out: "prefixedTest"
}]);

A nová kolekce prefixedTest bude vytvořen s dokumenty, které vypadají takto:

{ "_id" : ObjectId("XXX"), "name": "foo-bar" }

Jen jako odkaz je zde další zajímavá otázka na stejné téma s několika odpověďmi, které stojí za přečtení:Aktualizovat pole MongoDB pomocí hodnoty jiného pole



  1. MongoDB findOneAndDelete()

  2. blpop po chvíli zastaví zpracování fronty

  3. Existuje nějaké omezení počtu argumentů, které zvládnou příkazy redis, jako je ZADD nebo HMGET?

  4. Mongodb, souhrnný dotaz s $lookup