sql >> Databáze >  >> NoSQL >> MongoDB

MongoDB- Vložte, pokud neexistuje, jinak přeskočte

Zde máte dvě skutečné možnosti v závislosti na tom, jak chcete věci řešit:

  1. Použijte upsert funkčnost MongoDB v podstatě „vyhledat“, pokud klíčová data existují. Pokud ne, předáte data pouze do $setOnInsert a to se ničeho jiného nedotkne.

  2. Používejte operace "UnOrdered" hromadně. Celá dávka aktualizací bude pokračovat, i když se vrátí chyba, ale chybové zprávy jsou právě takové a vše, co není chybou, bude potvrzeno.

Celý příklad:

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

Všimněte si, že "změněná akce" v aktuálních ovladačích je, že výsledek odezvy na .execute() bude vracet chybový objekt, který má být vyvolán, kde předchozí verze tak nečinily s operacemi "Un-ordered".

Proto je nutné, aby váš kód nikdy nespoléhal na err vrátil sám a měli byste vložit vrácený result místo pro úplnou klasifikaci chyb.

Nicméně, když není objednáno, pak dávka pokračuje až do konce, bez ohledu na to, kolik chyb se vyskytne. Věci, které nejsou chybou, budou potvrzeny jako obvykle.

To opravdu přijde na to, "je důležitá sekvence". Pokud ano, pak potřebujete operace "Ordered" a duplicitním klíčům se můžete vyhnout pouze pomocí "upserts". V opačném případě použijte „neuspořádané“, ale dejte si pozor na návratové chyby a na to, co vlastně znamenají.

Také při použití .collection chcete-li získat základní objekt kolekce ze základního ovladače pro umožnění „hromadných“ operací, pak se vždy ujistěte, že byla vždy nejprve volána buď „nějaká“ metoda mongoose.

Bez toho neexistuje žádné zaručené připojení k databázi pomocí nativních metod ovladače, jak je zpracováno pro metody mongoose, takže operace selže kvůli žádnému připojení.

Alternativou k prvnímu „spuštění“ metody mongoose je zabalení logiky vaší aplikace do posluchače událostí pro připojení:

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


  1. Konfigurace MongoDB pro Spring Boot – „url“ s a bez ověřovacích pověření

  2. Node.js – Vytváření vztahů s Mongoose

  3. Jak převést BsonDocument na silně typovaný objekt pomocí oficiálního ovladače MongoDB C#?

  4. TTL pro člena sady