Node.js 迭代mongo数据的更快方法是什么?在批处理中查找与使用光标迭代?

Node.js 迭代mongo数据的更快方法是什么?在批处理中查找与使用光标迭代?,node.js,mongodb,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) { co

我的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;
}
const batchSize=1000;
const collection=mongo.client.collection('test');
常量计数=等待quizVersionCollection.count();
设iter=0;

而(iter*batchSize第一种方法更好,因为正如你所说的:每1000个文档只调用一次。因此,如果你逐个获取文档,你将节省所有生成的网络流量。 第二种方法需要大量的网络时间,因为它是一个接一个地获取文档

一些提示:

  • 在mongo查询中使用skip从来都不是一个好主意,因为 根据:

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

  • 将批处理大小设置为略小于16MB/(文档的平均大小)。这是因为mongoDB对响应大小有16MB的限制。这样可以最大限度地减少调用次数

  • 如果您可以使用多线程,将数据分成7组,在间隔边界获取
    ID
    ,并使用这些ID创建范围条件。然后您可以删除
    排序
    限制
    跳过
    。这将对性能产生巨大影响

  • 第一种方法更好,因为正如您所说的:每1000个文档只调用一次。因此,如果您逐个获取文档,您将保存生成的所有网络流量。 第二种方法需要大量的网络时间,因为它是一个接一个地获取文档

    一些提示:

  • 在mongo查询中使用skip从来都不是一个好主意,因为 根据:

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

  • 将批处理大小设置为略小于16MB/(文档的平均大小)。这是因为mongoDB对响应大小有16MB的限制。这样可以最大限度地减少调用次数

  • 如果您可以使用多线程,将数据分成7组,在间隔边界获取
    ID
    ,并使用这些ID创建范围条件。然后您可以删除
    排序
    限制
    跳过
    。这将对性能产生巨大影响

  • 导出和导入也可能是一个选项吗?这个性能主题通常取决于很多因素。恐怕您需要对它进行一些分析,以获得有意义的答案。@dnickless我需要进行一些操作和计算,因为我正在将它传输到Google BigQuery。导出和导入可能是一个选项吗,太好了?这个性能主题通常取决于很多因素。恐怕您需要对它进行一些记录分析,才能得到有意义的答案。@dnickless我需要做一些操作和计算,因为我正在将它传输到Google BigQuery。谢谢,我使用了您的解决方案,它工作得很好!谢谢,我使用了您的解决方案和它很好用!
    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;
      }