Anda memiliki dua pilihan nyata di sini tergantung pada bagaimana Anda ingin menangani berbagai hal:
-
Gunakan upsert fungsionalitas MongoDB untuk "mencari" pada dasarnya jika ada data kunci. Jika tidak maka Anda hanya meneruskan data ke
$setOnInsert
dan itu tidak akan menyentuh apa pun. -
Gunakan operasi "Tidak Berurutan" secara Massal. Seluruh kumpulan pembaruan akan berlanjut meskipun kesalahan dikembalikan, tetapi laporan kesalahan hanya itu, dan apa pun yang bukan kesalahan akan dilakukan.
Seluruh contoh:
var async = require('async'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
var testSchema = new Schema({
"_id": Number,
"name": String
},{ "_id": false });
var Test = mongoose.model('Test',testSchema,'test');
mongoose.connect('mongodb://localhost/test');
var data = [
{ "_id": 1, "name": "One" },
{ "_id": 1, "name": "Another" },
{ "_id": 2, "name": "Two" }
];
async.series(
[
// Start fresh
function(callback) {
Test.remove({},callback);
},
// Ordered will fail on error. Upserts never fail!
function(callback) {
var bulk = Test.collection.initializeOrderedBulkOp();
data.forEach(function(item) {
bulk.find({ "_id": item._id }).upsert().updateOne({
"$setOnInsert": { "name": item.name }
});
});
bulk.execute(callback);
},
// All as expected
function(callback) {
Test.find().exec(function(err,docs) {
console.log(docs)
callback(err);
});
},
// Start again
function(callback) {
Test.remove({},callback);
},
// Unordered will just continue on error and record an error
function(callback) {
var bulk = Test.collection.initializeUnorderedBulkOp();
data.forEach(function(item) {
bulk.insert(item);
});
bulk.execute(function(err,result) {
callback(); // so what! Could not care about errors
});
},
// Still processed the whole batch
function(callback) {
Test.find().exec(function(err,docs) {
console.log(docs)
callback(err);
});
}
],
function(err) {
if (err) throw err;
mongoose.disconnect();
}
);
Perhatikan bahwa "tindakan yang diubah" di driver saat ini adalah respons hasil pada .execute()
akan mengembalikan objek kesalahan yang akan dilempar, di mana rilis sebelumnya tidak melakukannya dengan operasi "Tidak Terurut".
Ini membuatnya penting bahwa kode Anda tidak pernah bergantung pada err
dikembalikan sendiri, dan Anda harus memeriksa result
. yang dikembalikan sebagai gantinya untuk klasifikasi lengkap kesalahan.
Meskipun demikian, ketika tidak berurutan maka batch berlanjut hingga akhir, tidak peduli berapa banyak kesalahan yang terjadi. Hal-hal yang bukan merupakan kesalahan akan dilakukan seperti biasa.
Ini benar-benar bermuara pada "adalah urutan penting". Jika demikian, maka Anda memerlukan operasi "Dipesan" dan Anda hanya dapat menghindari kunci duplikat dengan menggunakan "upserts". Jika tidak, gunakan "tidak berurutan", tetapi waspadai pengembalian kesalahan dan apa artinya sebenarnya.
Juga, saat menggunakan .collection
untuk mendapatkan objek koleksi yang mendasari dari driver dasar untuk mengaktifkan operasi "Massal", maka selalu pastikan bahwa salah satu metode luwak "beberapa" selalu dipanggil terlebih dahulu.
Tanpa itu, tidak ada jaminan koneksi ke database dengan metode driver asli karena ditangani untuk metode luwak, sehingga operasi akan gagal karena tidak ada koneksi.
Alternatif untuk "menembak" metode luwak terlebih dahulu, adalah dengan membungkus logika aplikasi Anda dalam event listener untuk koneksi:
mongoose.connection.on("open",function(err) {
// app logic in here
})