sql >> Database >  >> NoSQL >> MongoDB

MongoDB Node.js native driver slikt stilletjes `bulkWrite` uitzondering

Dus zoals gezegd:"Het is een bug". De bug is met name hier :

 // 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);
    });
  });

Het probleem is dat de "respons" ( of r ) in de callback die wordt verpakt in een Promise is eigenlijk niet null , en daarom, ondanks dat de fout aanwezig is, is de voorwaarde daarom niet true en reject(err) wordt niet aangeroepen, maar de resolve(r) wordt verzonden en daarom wordt dit niet als een uitzondering beschouwd.

Correctie zou wat triage vereisen, maar u kunt ofwel 'omzeilen' zoals vermeld door de writeErrors te inspecteren eigenschap in het antwoord van de huidige bulkWrite() implementatie of overweeg een van de andere alternatieven als:

De Bulk API-methoden rechtstreeks gebruiken:

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();
  }

})();

Prima, maar heeft natuurlijk de kwestie van niet natuurlijk terugvallen op serverimplementaties zonder Bulk API-ondersteuning om in plaats daarvan de legacy API-methoden te gebruiken.

De belofte handmatig nakomen

(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);
  }

})();

Zoals opgemerkt ligt het probleem in de implementatie van hoe bulkWrite() keert terug als een Promise . Dus in plaats daarvan kun je coderen met de callback() formulier en doe je eigen Promise inpakken om te doen wat je ervan verwacht.

Nogmaals, zoals opgemerkt, heeft het een JIRA-probleem en Triage nodig, wat de juiste manier is om met uitzonderingen om te gaan. Maar hopelijk wordt het snel opgelost. Kies ondertussen een aanpak van bovenaf.




  1. MongoDB $pull

  2. Hoe u dubbele sleutelfouten veilig kunt negeren met insert_many

  3. Operator $arrayElemAt in aggregatie met Mongo <3.2

  4. BsonSerializationException treedt op als de elementnaam eindigt op een punt