在不重载内存的情况下,修改大型MongoDB集合中每个文档的最佳方法是什么?

时间:2015-04-10 01:21:15

标签: node.js mongodb mongoose

目前我正在执行此任务:

var skip = 0;
var limit = 5;

gulp.task('add coordinates to visits', function(done) {

(function recurse() {

    Visit.find({})
        .skip(skip)
        .limit(limit)
        .populate('zone')

    .exec(function cb(err, visits) {
        if (err) {
            throw err;
        }
        if (visits.length === 0) {
            return;
        }

        async.each(visits, function iterateEvents(visit, next) {
            if (!visit.zone) {
                return next();
            } else if (!visit.coordinates.lat || !visit.coordinates.lng) {
                visit.coordinates = {
                    lat: visit.zone.geo.coordinates.lat,
                    lng: visit.zone.geo.coordinates.lng
                };
            }
            visit.save(next);

        }, function cb(err) {
            if (err) {
                throw err;
            }

            skip += limit;
            setTimeout(recurse, 1000);
        });

    });

})();

});

但我确信必须有比使用skiplimit,`setTimeout更优雅和最优的方法。是否有一些用于运行更新任务的mongo或mongoose方法?

1 个答案:

答案 0 :(得分:1)

根据我们在评论中的对话,似乎Mongoose的querystream可能就是您所寻找的:

var stream = Visits.find().populate('zone').stream();

stream.on('data', function processDoc(visit) {
  var self = this;

  if (visit.zone && (!visit.coordinates.lat || !visit.coordinates.lng)) {
    self.pause();

    visit.update({
      coordinates: {
        lat: visit.zone.geo.coordinates.lat,
        lng: visit.zone.geo.coordinates.lng
      }
    }, function(err, result) {
      if (err) { console.log(err); };
      self.resume();
    });
  }
});

stream.on('error', function(err) {
  console.log('error', err);
});

stream.on('close', function() {
  console.log('closed');
});