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

Driver asli MongoDB Node.js secara diam-diam menelan pengecualian `bulkWrite`

Jadi seperti yang dikomentari, "Ini bug". Secara khusus bugnya adalah di sini :

 // Return a Promise
  return new this.s.promiseLibrary(function(resolve, reject) {
    bulkWrite(self, operations, options, function(err, r) {
      if(err && r == null) return reject(err);
      resolve(r);
    });
  });

Masalahnya adalah "respon" ( atau r ) dalam panggilan balik yang dibungkus dengan Promise sebenarnya bukan null , dan oleh karena itu meskipun ada kesalahan, kondisinya tidak true dan reject(err) tidak dipanggil, melainkan resolve(r) sedang dikirim dan karenanya ini tidak dianggap sebagai pengecualian.

Memperbaiki akan membutuhkan beberapa triase, tetapi Anda dapat 'menyelesaikan' seperti yang disebutkan dengan memeriksa writeErrors properti dalam respons dari bulkWrite() current saat ini implementasi atau pertimbangkan salah satu alternatif lain sebagai:

Menggunakan metode Massal API secara langsung:

const MongoClient = require('mongodb').MongoClient,
      uri  = 'mongodb://localhost:27017/myNewDb';

(async () => {

  let db;

  try {

    db = await MongoClient.connect(uri);

    let bulk = db.collection('myNewCollection').initializeOrderedBulkOp();

    bulk.find({ foo: 'bar' }).upsert().updateOne({
      $setOnInsert: { count: 0 },
      $inc: { count: 0 }
    });

    let result = await bulk.execute();
    console.log(JSON.stringify(result,undefined,2));

  } catch(e) {
    console.error(e);
  } finally {
    db.close();
  }

})();

Baik-baik saja, tetapi tentu saja memiliki masalah untuk tidak mundur secara alami pada implementasi server tanpa dukungan API Massal untuk menggunakan metode API lama.

Membungkus Janji Secara Manual

(async () => {

  let db = await require('mongodb').MongoClient.connect('mongodb://localhost:27017/myNewDb');

  let mongoOps = [{
    updateOne: {
      filter: { foo: "bar" },
      update: {
        $setOnInsert: { count:0 },
        $inc: { count:1 },
      },
      upsert: true,
    }
  }];

  try {
    let result = await new Promise((resolve,reject) => {

      db.collection("myNewCollection").bulkWrite(mongoOps, (err,r) => {
        if (err) reject(err);
        resolve(r);
      });
    });
    console.log(JSON.stringify(result,undefined,2));
    console.log("Success!");
  } catch(e) {
    console.log("Failed:");
    console.log(e);
  }

})();

Seperti disebutkan masalahnya terletak pada implementasi bagaimana bulkWrite() kembali sebagai Promise . Jadi, alih-alih Anda dapat membuat kode dengan callback() bentuk dan lakukan Promise Anda sendiri membungkus untuk bertindak seperti yang Anda harapkan.

Sekali lagi seperti yang disebutkan, perlu masalah JIRA dan Triase yang merupakan cara yang benar untuk menangani pengecualian. Tapi semoga segera teratasi. Sementara itu, pilih pendekatan dari atas.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Pembaruan MongoDB:Hasilkan bidang baru berdasarkan bidang yang ada, atau perbarui di tempat

  2. Perbarui dokumen MongoEngine menggunakan python dict?

  3. Luwak unshift findAndUpdateById

  4. Tambahkan bidang yang tidak ada dalam skema dengan luwak

  5. Apakah kerangka Agregasi Mongodb lebih cepat dari peta/kurangi?