Seperti disebutkan, masalah utama di sini adalah dengan pembaruan pada beberapa elemen dengan operator posisi seperti yang tercatat dalam masalah lama ini:http://jira.mongodb.org/browse/SERVER-1243
Oleh karena itu, kasus dasarnya adalah tidak ada eksekusi tunggal yang dapat melakukan ini, jadi untuk memproses beberapa elemen array, Anda memerlukan beberapa metode untuk menentukan berapa banyak elemen yang perlu Anda perbarui dan memproses satu pernyataan pembaruan per setiap elemen.
Pendekatan yang disederhanakan biasanya menggunakan Operasi Massal untuk memproses apa yang akhirnya menjadi operasi pembaruan "banyak" sebagai satu permintaan dan tanggapan ke server:
var bulk = db.collection.initializeOrderedBulkOp(),
count = 0;
db.collection.find({ "name": "John Doe", "adds.status": "PENDING" }).forEach(function(doc) {
doc.adds.filter(function(add){ return add.status = "PENDING" }).forEach(function(add) {
bulk.find({ "_id": doc._id, "adds.status": "PENDING" }).updateOne({
"$set": { "adds.$.status": "APPROVED" }
});
count++;
// Execute once in 1000 statements created and re-init
if ( count % 1000 == 0 ) {
bulk.execute();
bulk = db.collection.initializeOrderedBulkOp();
}
});
});
// Execute any pending operations
if ( count % 1000 != 0 )
bulk.execute();
Jika dokumen Anda yang diperbarui cukup kecil, atau memang hanya satu dokumen maka Anda dapat melupakan count
periksa dan cukup tambahkan semua pembaruan massal dalam loop yang diperlukan dan cukup jalankan sekali di akhir semua loop.
Penjelasan dan alternatif yang lebih panjang dapat ditemukan di Cara Memperbarui Beberapa Elemen Array
, tetapi semua bermuara pada pendekatan berbeda untuk mencocokkan elemen guna memperbarui dan memproses posisi $
perbarui beberapa kali, baik untuk setiap dokumen yang cocok atau sampai tidak ada lagi dokumen yang dimodifikasi yang dikembalikan.