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