如何异步保存100万条记录到mongodb?

时间:2015-01-22 11:27:28

标签: javascript node.js mongodb mongoose mongodb-query

我想使用这样的javascript将100万条记录保存到mongodb:

for (var i = 0; i<10000000; i++) {
  model = buildModel(i);
  db.save(model, function(err, done) {
    console.log('cool');
  });
}

我试过了,它保存了~160条记录,然后挂了2分钟,然后退出。为什么呢?

2 个答案:

答案 0 :(得分:4)

它爆炸了,因为你没有等待异步调用完成,然后再继续下一次迭代。这意味着你正在构建一个&#34;堆栈&#34;未解决的操作直到导致问题。这个网站又叫什么名字?得到照片?

因此,这不是继续进行"Bulk"插入的最佳方式。幸运的是,除了前面提到的回调问题之外,底层MongoDB驱动程序已经考虑过这个问题。实际上有一个"Bulk API"可以使这更好。假设您已将本机驱动程序作为db对象提取。但我更喜欢使用模型中的.collection访问器和"async"模块来使一切清晰:

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

区别在于使用&#34;异步&#34;完成时的回调方法,而不仅仅是构建堆栈,还使用&#34;批量操作API&#34;通过在1000个条目的批量更新语句中提交所有内容来缓解异步写入调用。

这不仅不是&#34;建立一个堆栈&#34;函数执行就像你自己的示例代码一样,但也执行高效的&#34; wire&#34;交易不是通过个人陈述发送所有内容,而是分解成可管理的批次&#34;服务器承诺。

答案 1 :(得分:3)

您应该使用类似Async's eachLimit的内容:

// Create a array of numbers 0-999999
var models = new Array(1000000);
for (var i = models.length; i >= 0; i--)
  models[i] = i;

// Iterate over the array performing a MongoDB save operation for each item
// while never performing more than 20 parallel saves at the same time
async.eachLimit(models, 20, function iterator(model, next){
  // Build a model and save it to the DB, call next when finished
  db.save(buildModel(model), next);
}, function done(err, results){
  if (err) { // When an error has occurred while trying to save any model to the DB
    console.error(err);
  } else { // When all 1,000,000 models have been saved to the DB
    console.log('Successfully saved ' + results.length + ' models to MongoDB.');
  }
});