我遇到的情况是说我在mongo中有200万个文档,我想以100或1000个批处理(因为v8内存不足),并且在读取文档的批处理大小之后,我想进行一些计算并将其写入可能要超过10分钟的文件,然后我才能获得下一组批处理大小的文档。我该如何使用node.js mongo db驱动程序呢?

我在node.js mongo数据库驱动程序中找不到我需要的所有方法。例如mongo shell有docs.leftInTheBatch,它可以告诉当前批处理中剩余多少文档,而在node.js中则不可用。

我在node.js mongo数据库驱动程序中寻找的另一个重要功能是如何将光标设置为不超时(这在mongo shell和其他语言驱动程序中是可能的,但是我不确定在node.js上)?

   var hash_map = {};
    db.collection(collection_name).find().batchSize(100).each(function(err, docs) {
        docs.each(function(err, doc) {
            var id = doc._id; // assume this is a string not objectID
            hash_map[id] = doc.key1;
        })
        // This async function would take say 20 minutes or just assume it takes long time. now, would the cursor time out before I retrieve the next batch?
        async.series([
            prcocessData.bind(null, hash_map),
            writeDataToFile
        ], function(err){
           if(err) throw err;
           return callback();
        });
    });

最佳答案

这是对“ batchSize”用法的错误解释。这意味着(尽管使用了驱动程序方法,但实际上基本上是作为.find()的游标返回的参数)该服务器将一次返回100个结果(在这种情况下)的“批处理”,然后将被迭代为“光标”。

您缺少“光标”的概念。您不会“实际上”返回在整体结果中包含100记录或“收集项目”的“数据”结果。您只有一个“指针”,它允许您一次在.next()方法上“获取”单个“记录/文档”。

诸如.each().toArray()的便利方法适用于“较小”的结果集,其中结果基本上被“转换”为数组以进行进一步处理。通过.toArray()手动或通过类似.each()的方法隐式进行。

对于大型结果集,您需要节点和MongoDB驱动程序提供的“流” API。有关如何在当前版本上调用该文档,请参见文档中的here

默认情况下,较新版本的MongoDB节点驱动程序将返回node stream接口。

需要指出的是,您“可以”在此处使用光标修饰符(例如.limit()),然后在“页面”中“循环”结果,但是在您的上下文中,这不是最有效的方法。查看链接所引用的流API。

关于node.js - 如何在不使 Node mongodb光标超时的情况下批量处理文档,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27666770/

10-16 20:02