sql >> Database teknologi >  >> NoSQL >> MongoDB

MongoDB- Indsæt hvis det ikke findes, ellers spring over

Du har to reelle valg her, alt efter hvordan du vil håndtere tingene:

  1. Brug upsert funktionalitet af MongoDB til i det væsentlige at "slå op", hvis nøgledataene findes. Hvis ikke, så videregiver du kun data til $setOnInsert og det vil ikke røre noget andet.

  2. Brug "Ubestilte" operationer i bulk. Hele partiet af opdateringer fortsætter, selvom der returneres en fejl, men fejlrapporten(erne) er netop det, og alt, der ikke er en fejl, vil blive begået.

Helt eksempel:

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

Bemærk, at den "ændrede handling" i aktuelle drivere er, at resultatsvaret på .execute() vil returner et fejlobjekt, der skal kastes, hvor tidligere udgivelser ikke gjorde det med "Ikke-ordrede" operationer.

Dette gør det bydende nødvendigt, at din kode aldrig er afhængig af err returneres alene, og du burde inspetere det returnerede result i stedet for den fulde klassificering af fejl.

Ikke desto mindre, når den ikke er bestilt, fortsætter partiet indtil slutningen, uanset hvor mange fejl der opstår. Ting, der ikke er en fejl, vil blive begået som normalt.

Dette kommer virkelig ned til "er sekvens vigtig". Hvis ja, så har du brug for "Bestilte" operationer, og du kan kun undgå duplikerede nøgler ved at bruge "upserts". Ellers brug "uordnet", men vær opmærksom på fejlen, og hvad de rent faktisk betyder.

Også når du bruger .collection for at få det underliggende samlingsobjekt fra basisdriveren til at aktivere "Bulk"-operationer, skal du altid være sikker på, at enten "en eller anden" mongoose-metode altid er blevet kaldt først.

Uden det er der ingen garanteret forbindelse til databasen med de native driver-metoder, da den håndteres for mongoose-metoderne, så operationen vil mislykkes på grund af ingen forbindelse.

Alternativet til at "affyre" en mangustmetode først, er at pakke din applogik ind i en begivenhedslytter for forbindelsen:

mongoose.connection.on("open",function(err) {
    // app logic in here
})


  1. 7 måder at tælle dokumenter i MongoDB

  2. Find og modificer med MongoDB C#

  3. Spring Data MongoDB – Indekser, annoteringer og konvertere

  4. Sådan dropper du indeks ved hjælp af Mongoose