Anda tidak dapat merujuk ke nilai dokumen yang ingin Anda perbarui, jadi Anda memerlukan satu kueri untuk mengambil dokumen dan kueri lainnya untuk memperbaruinya. Sepertinya ada permintaan fitur
untuk itu di OPEN
negara bagian sejak 2016.
Jika Anda memiliki koleksi dengan dokumen seperti:
{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name" : "bar" }
Menggunakan shell MongoDB, Anda dapat melakukan sesuatu seperti ini:
db.test.find({ name: "bar" }).snapshot().forEach((doc) => {
doc.name = "foo-" + doc.name;
db.test.save(doc);
});
Dokumen akan diperbarui seperti yang diharapkan:
{ "_id" : ObjectId("590a4aa8ff1809c94801ecd0"), "name": "foo-bar" }
Perhatikan .snapshot()
call.Ini memastikan bahwa kueri tidak akan mengembalikan dokumen beberapa kali karena operasi penulisan yang mengganggu memindahkannya karena pertumbuhan ukuran dokumen.
Menerapkan ini ke contoh Mongoose Anda, seperti yang dijelaskan dalam contoh resmi ini :
Cat.findById(1, (err, cat) => {
if (err) return handleError(err);
cat.name = cat.name + "bar";
cat.save((err, updatedCat) => {
if (err) return handleError(err);
...
});
});
Perlu disebutkan bahwa ada $concat
operator dalam kerangka agregasi, tetapi sayangnya Anda tidak dapat menggunakannya dalam update
kueri.
Bagaimanapun, tergantung pada apa yang perlu Anda lakukan, Anda dapat menggunakannya bersama dengan $out
operator untuk menyimpan hasil agregasi ke koleksi baru.
Dengan contoh yang sama, Anda akan melakukan:
db.test.aggregate([{
$match: { name: "bar" }
}, {
$project: { name: { $concat: ["foo", "-", "$name"] }}
}, {
$out: "prefixedTest"
}]);
Dan koleksi baru prefixedTest
akan dibuat dengan dokumen yang terlihat seperti:
{ "_id" : ObjectId("XXX"), "name": "foo-bar" }
Sebagai referensi, ada pertanyaan menarik lainnya tentang topik yang sama dengan beberapa jawaban yang layak dibaca:Perbarui bidang MongoDB menggunakan nilai bidang lain