MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Apa pendekatan yang tepat untuk memperbarui banyak catatan di MongoDB menggunakan Mongoose

Pendekatan membangun kriteria yang terdiri dari semua id dokumen dan kemudian melakukan pembaruan pasti akan menyebabkan masalah potensial. Saat Anda mengulangi daftar dokumen yang mengirim operasi pembaruan dengan setiap dokumen, di Mongoose Anda berisiko meledakkan server Anda terutama ketika berurusan dengan kumpulan data besar karena Anda tidak menunggu panggilan asinkron untuk diselesaikan sebelum pindah ke yang berikutnya pengulangan. Anda pada dasarnya akan membangun "tumpukan" operasi yang belum terselesaikan hingga ini menyebabkan masalah - Stackoverflow.

Ambil contoh, seandainya Anda memiliki larik id dokumen yang ingin Anda perbarui dokumen yang cocok pada bidang status:

const processedIds = [
  "57a0a96bd1c6ef24376477cd",
  "57a052242acf5a06d4996537",
  "57a052242acf5a06d4996538"
];

tempat Anda dapat menggunakan updateMany() metode

Model.updateMany(
  { _id: { $in: processedIds } }, 
  { $set: { status: "processed" } }, 
  callback
);

atau sebagai alternatif untuk kumpulan data yang sangat kecil, Anda dapat menggunakan forEach() metode pada larik untuk mengulanginya dan memperbarui koleksi Anda:

processedIds.forEach(function(id)){
  Model.update({ _id: id}, { $set: { status: "processed" } }, callback);
});

Di atas tidak apa-apa untuk kumpulan data kecil. Namun, ini menjadi masalah ketika Anda dihadapkan dengan ribuan atau jutaan dokumen untuk diperbarui karena Anda akan membuat panggilan server berulang dari kode asinkron dalam loop.

Untuk mengatasinya gunakan sesuatu seperti async eachLimit dan ulangi array yang melakukan operasi pembaruan MongoDB untuk setiap item sambil tidak pernah melakukan lebih dari x pembaruan paralel secara bersamaan.

Pendekatan terbaik adalah menggunakan API massal untuk ini yang sangat efisien dalam memproses pembaruan secara massal. Perbedaan kinerja vs pemanggilan operasi pembaruan pada setiap satu dari banyak dokumen adalah bahwa alih-alih mengirim permintaan pembaruan ke server dengan setiap iterasi, API massal mengirimkan permintaan sekali dalam setiap 1000 permintaan (batch).

Untuk versi luwak >=4.3.0 yang mendukung Server MongoDB 3.2.x , Anda dapat menggunakan bulkWrite() untuk pembaruan. Contoh berikut menunjukkan bagaimana Anda dapat melakukannya:

const bulkUpdateCallback = function(err, r){
  console.log(r.matchedCount);
  console.log(r.modifiedCount);
}

// Initialize the bulk operations array
const bulkUpdateOps = [], counter = 0;

processedIds.forEach(function (id) {
  bulkUpdateOps.push({
    updateOne: {
      filter: { _id: id },
      update: { $set: { status: "processed" } }
    }
  });
  counter++;

  if (counter % 500 == 0) {
    // Get the underlying collection via the Node.js driver collection object
    Model.collection.bulkWrite(bulkUpdateOps, { ordered: true, w: 1 }, bulkUpdateCallback);
    bulkUpdateOps = []; // re-initialize
  }
})

// Flush any remaining bulk ops
if (counter % 500 != 0) {
  Model.collection.bulkWrite(bulkOps, { ordered: true, w: 1 }, bulkUpdateCallback);
}

Untuk versi luwak ~3.8.8 , ~3.8.22 , 4.x yang mendukung Server MongoDB >=2.6.x , Anda dapat menggunakan API Massal sebagai berikut

var bulk = Model.collection.initializeOrderedBulkOp(),
    counter = 0;

processedIds.forEach(function(id) {
    bulk.find({ "_id": id }).updateOne({ 
        "$set": { "status": "processed" }
    });

    counter++;
    if (counter % 500 == 0) {
        bulk.execute(function(err, r) {
           // do something with the result
           bulk = Model.collection.initializeOrderedBulkOp();
           counter = 0;
        });
    }
});

// Catch any docs in the queue under or over the 500's
if (counter > 0) {
    bulk.execute(function(err,result) {
       // do something with the result here
    });
}


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. meneruskan luwak sebagai argumen ke suatu fungsi

  2. Bagaimana cara menggunakan C # untuk memasukkan dokumen ke dalam dokumen tertanam yang ada?

  3. Mainkan:Cara mengubah JSON saat menulis/membacanya ke/dari MongoDB

  4. Mengapa mendapatkan kesalahan saat memperbarui MongoDb?

  5. MongoDB $anyElementTrue