MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Comment enregistrer 1 million d'enregistrements dans mongodb de manière asynchrone ?

Il a explosé parce que vous n'attendez pas qu'un appel asynchrone se termine avant de passer à l'itération suivante. Cela signifie que vous construisez une "pile" d'opérations non résolues jusqu'à ce que cela pose un problème. C'est quoi le nom de ce site déjà ? Vous avez la photo ?

Ce n'est donc pas la meilleure façon de procéder avec "Bulk" insertions. Heureusement, le pilote MongoDB sous-jacent a déjà pensé à cela, mis à part le problème de rappel mentionné précédemment. Il existe en fait une "Bulk API" disponible pour rendre tout cela beaucoup mieux. Et en supposant que vous avez déjà extrait le pilote natif en tant que db objet. Mais je préfère simplement utiliser le .collection accesseur du modèle, et le "async" module pour que tout soit clair :

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 différence est d'utiliser les deux méthodes de rappel "asynchrones" à la fin plutôt que de simplement créer une pile, mais également d'utiliser "l'API d'opérations en bloc" afin d'atténuer les appels d'écriture asynchrones en soumettant tout dans des instructions de mise à jour par lots de 1000 entrées. /P>

Cela non seulement ne "construit pas une pile" d'exécution de fonction comme votre propre exemple de code, mais effectue également des transactions "filaires" efficaces en n'envoyant pas tout dans des instructions individuelles, mais plutôt en se divisant en "lots" gérables pour l'engagement du serveur .