EDIT
Detail yang hilang dari pertanyaan adalah bahwa bidang yang harus diperbarui sebenarnya ada di sub-dokumen . Ini sangat mengubah jawaban:
Ini adalah kendala dari apa yang Anda mungkin lakukan dengan memperbarui elemen array. Dan ini dijelaskan dengan jelas dalam dokumentasi . Sebagian besar di paragraf ini:
Jadi inilah masalahnya. Mencoba memperbarui semua elemen array dalam satu pernyataan seperti ini tidak kerja. Untuk melakukan ini, Anda harus melakukan hal berikut.
db.warehouses.find({ "items.qty": { "$gt": 0 } }).forEach(function(doc) {
doc.items.forEach(function(item) {
item.qty = 0;
});
db.warehouses.update({ "_id": doc._id }, doc );
})
Yang pada dasarnya adalah cara memperbarui setiap elemen larik.
multi pengaturan di .update()
berarti di beberapa "dokumen". Itu tidak bisa diterapkan ke beberapa elemen array. Jadi saat ini pilihan terbaik adalah mengganti semuanya. Atau dalam kasus ini, sebaiknya kita mengganti keseluruhan dokumen karena kita harus tetap melakukannya.
Untuk nyata data massal, gunakan db.eval() . Tapi harap baca dokumentasikan terlebih dahulu:
db.eval(function() {
db.warehouses.find({ "items.qty": { "$gt": 0 } }).forEach(function(doc) {
doc.items.forEach(function(item) {
item.qty = 0;
});
db.warehouses.update({ "_id": doc._id }, doc );
});
})
Memperbarui semua elemen dalam larik di seluruh keseluruhan koleksi tidak sederhana.
Asli
Cukup banyak persis apa yang dikatakan kesalahan itu. Untuk menggunakan operator posisi, Anda harus mencocokkan sesuatu yang pertama. Seperti dalam:
db.warehouses.update(
// query
{
_id:ObjectId('5322f07e139cdd7e31178b78'),
"items.qty": { "$gt": 0 }
},
// update
{
$set:{"items.$.qty":0}
},
// options
{
"multi" : true,
"upsert" : true
}
);
Jadi di mana cocok kondisi menentukan posisi dari item yang kurang dari 0 maka indeks diteruskan ke operator posisi.
PS :Saat muti apakah benar artinya diperbarui setiap dokumen. Biarkan false
jika maksud Anda hanya satu . Yang mana defaultnya.