Node.JS + mongo:.find()。each()在第一批后停止

这让我难住了。

我有一个独立的(命令行执行的)节点脚本,其目的是遍历大型集合中的所有文档(数十万个),并为每个文档执行一些计算,运行一些额外的JS代码,然后用一些新的值更新文档。

根据cursor.each()的文档 ,一旦我从collection.find()获得游标, .each(cb)方法应该对整个集合中的每个项目执行cb(item)

示例代码:

 myDb.collection('bigcollection').find().each(function(err, doc) { if (err) { console.log("Error: " + err); } else { if (doc != null) { process.stdout.write("."); } else { process.stdout.write("X"); } } }); 

我希望这样做是打印出数十万. 然后在最后打印一个X ,因为cursor.each()应该是“迭代该游标的所有文档”,并且根据示例代码“如果该项为null,则游标被耗尽/为空并closures“。

但是, 实际上做的是精确地打印出101 . 没有一个X在最后。

如果我调整批量大小( .find().batchSize(10).each(... ),它会在.find().batchSize(10).each(...之前精确地处理这些文档。

那么,为什么只处理第一批? 我不知何故误读.each()的文档? 这是否与这是一个命令行脚本的事实有关,并且在第二批结果返回之前,整个脚本以某种方式退出,或者什么? 如果是这样,我怎么确定它实际上处理所有的结果?

作为一个侧面节点,我尝试过使用.stream()和.forEach(),并且在这两种情况下,它都会在第一批之后进行沟渠。

更新:嗯,这很有趣。 只是尝试连接到我的生产服务器,而不是我的本地主机上的mongo实例,瞧,它运行通过整个集合像它应该。 服务器运行mongodb 3.0.6,我的本地实例是3.2.3。 我的版本的节点mongodb驱动程序是2.0.43。

我收集了200个文件,下面的代码很顺利。 换句话说,不能重现问题。 正如你所看到的,我已经将批量减less到了10个。

 var url = 'mongodb://localhost:27017/test'; MongoClient.connect(url, function(err, db) { if (err) { console.log(err); } else { var counter = 0; db.collection('collection').find({}).batchSize(10).each(function(e, r){ if(err){ console.log("E: " + err); db.close(); } else{ if(r == null){ db.close(); } else{ counter += 1; console.log("X: " + counter); } } }); } }); 

如果你仍然面临同样的问题,我build议将MongoDB驱动程序更新到最新版本。 由于驱动程序正在积极开发之中,有时候会有一些bug悄然进入发布版本,造成奇怪的行为。