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

Come salvare 1 milione di record su mongodb in modo asincrono?

È esploso perché non stai aspettando il completamento di una chiamata asincrona prima di passare all'iterazione successiva. Ciò significa che stai costruendo una "pila" di operazioni irrisolte fino a quando ciò non causa un problema. Come si chiama di nuovo questo sito? Hai la foto?

Quindi questo non è il modo migliore per procedere con "Bulk" inserzioni. Fortunatamente il driver MongoDB sottostante ha già pensato a questo, a parte il problema di callback menzionato in precedenza. Esiste infatti una "Bulk API" disponibile per renderlo molto migliore. E supponendo che tu abbia già estratto il driver nativo come db oggetto. Ma preferisco semplicemente usare il .collection accessor dal modello e "async" modulo per chiarire tutto:

var bulk = Model.collection.initializeOrderedBulkOp();
var counter = 0;

async.whilst(
  // Iterator condition
  function() { return count < 1000000 },

  // Do this in the iterator
  function(callback) {
    counter++;
    var model = buildModel(counter);
    bulk.insert(model);

    if ( counter % 1000 == 0 ) {
      bulk.execute(function(err,result) {
        bulk = Model.collection.initializeOrderedBulkOp();
        callback(err);
      });
    } else {
      callback();
    }
  },

  // When all is done
  function(err) {
    if ( counter % 1000 != 0 ) 
        bulk.execute(function(err,result) {
           console.log( "inserted some more" );
        });        
    console.log( "I'm finished now" ;
  }
);

La differenza sta nell'usare entrambi i metodi di callback "asincroni" al completamento piuttosto che semplicemente nella creazione di uno stack, ma anche nell'utilizzo dell'"API per operazioni in blocco" per mitigare le chiamate di scrittura asincrone inviando tutto in istruzioni di aggiornamento batch di 1000 voci.

Questo non solo non "accumula uno stack" di esecuzione delle funzioni come il tuo codice di esempio, ma esegue anche efficienti transazioni "wire" non inviando tutto in singole istruzioni, ma suddividendole in "batch" gestibili per l'impegno del server .