如何从Mongo获取大型数据集到数组?

时间:2017-12-30 11:22:01

标签: node.js mongodb performance

我有150.000个元素的集合。它的大小不到150MB。 出于测试原因,我想把它放到数组中。这是相对少量的数据,所以我希望它应该没有任何问题。不是这样。

我之前的编辑是关于shell和NodeJS之间的区别,但我认为现在不是这一点,所以我编辑了帖子以代表更有趣的问题。

Rig:我的驱动程序版本是3,Mongo版本是3.6。我使用最新的NodeJS作为主要工具。 8GB RAM。

因此,有两种基本方法可以将集合项目添加到数组中。

测试脚本(使用时刻)

exports.testMongoLoad = function() {
  console.log("started");
  var m1 = moment();
  testMongoLoad2(function(err, docs) {
    if (err) console.log(err);
    var m2 = moment();
    console.log(
      "Returned " +
        docs.length +
        " documents in " +
        m2.diff(m1, "ms") +
        " ms as array"
    );
  });
};

toArray()函数

testMongoLoad1 = function(callback) {
  db
        .get()
        .collection("matchesn")
        .find({})
        .toArray(function(err, docs) {
          if (err) return callback(err);
          return callback(null, docs);
        });
    };

~8秒

每个()函数

testMongoLoad2 = function(callback) {
  docs = [];
  db
    .get()
    .collection("matchesn")
    .find({})
    //.project({ _id: 1 })
    .each(function(err, doc) {
      if (doc) {
        docs.push(doc);
      } else {
        return callback(null, docs);
      }
    });
};

~8秒

如果我使用project,我会在 ~1秒内获得结果

如果我只使用150000个元素填充一些数组(请参阅我的评论),它将在 ~60 ms完成

那么,正确的方法是什么?可以这样做,还是100%禁止驱动程序级别进行此类操作?

UPD

基本上toArray实施正在执行next,直到什么都没有 toArray source code

var toArray = function(self, callback) {
  var items = [];

  // Reset cursor
  self.rewind();
  self.s.state = Cursor.INIT;

  // Fetch all the documents
  var fetchDocs = function() {
    self._next(function(err, doc) {
      if (err) return handleCallback(callback, err);
      if (doc == null) {
        return self.close({ skipKillCursors: true }, () => handleCallback(callback, null, items));
      }

      // Add doc to items
      items.push(doc);

      // Get all buffered objects
      if (self.bufferedCount() > 0) {
        var docs = self.readBufferedDocuments(self.bufferedCount());

        // Transform the doc if transform method added
        if (self.s.transforms && typeof self.s.transforms.doc === 'function') {
          docs = docs.map(self.s.transforms.doc);
        }

        push.apply(items, docs);
      }

      // Attempt a fetch
      fetchDocs();
    });
  };

  fetchDocs();
};

0 个答案:

没有答案