迭代mongo数据的更快方法是什么?批量查找与游标迭代?

时间:2018-08-10 12:25:12

标签: node.js mongodb

我的mongo集合中有超过1000万条记录,希望移至其他数据库。

有两种方法可以实现该目的:

使用find批处理数据

const batchSize = 1000;
const collection = mongo.client.collection('test');
const count = await quizVersionCollection.count();
let iter = 0;
while (iter * batchSize <= count) {
  const dataArr = await collection.find({})
                  .sort({ _id: -1 })
                  .limit(batchSize)
                  .skip(iter * batchSize)
                  .toArray();
  iter += 1;
}

使用mongo光标

while (yield cursor.hasNext()) {
    const ids = [];
    const batchSize = 1000;
    for (let i = 0; i < batchSize; i += 1) {
      if (yield cursor.hasNext()) {
        ids.push((yield cursor.next())._id);
      }
    }
    done += batchSize;
  }

在第一种方法中,我对每1000个文档提出一个请求,而在第二种方法中,我对每个文档提出2个请求。就速度和计算而言,哪种方法更好?

1 个答案:

答案 0 :(得分:1)

第一种方法更好,因为正如您所说:每1000个文档仅发出一次调用。因此,您将保存所有如果一一获得文件便会产生的网络流量。 第二种方法将花费大量的网络时间,因为它是一个一个地获取文档。

一些提示:

  1. 在mongo查询中使用skip绝不是一个好主意,因为 根据{{​​3}}:

      

    cursor.skip()方法要求服务器从输入结果集的开头开始扫描,然后再开始返回结果。随着偏移量的增加,cursor.skip()会变慢。

  2. 将批处理大小设置为仅小于16MB /(文档的平均大小)。这是因为mongoDB的响应大小限制为16MB。这样,您可以最大程度地减少拨打电话的次数。

  3. 如果可以使用多线程,请将数据分为7组,在区间边界获取ids,然后使用这些ID创建范围条件。然后,您可以删除sortlimitskip。这将对性能产生巨大影响。