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

Node.JS + mongo: .find().each() stopping after first batch

这让我难住了。

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

根据 cursor.each()documentation,一旦我从 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() 应该 "Iterate over all the documents for this cursor," 并且根据示例代码,"If the item is null then the cursor is exhausted/empty and closed."

但它 实际上 所做的是精确地打印出 101 .,最后没有 X

如果我调整批处理大小 (.find().batchSize(10).each(...),它会在提取之前准确地处理该数量的文档。

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

作为侧节点,我尝试使用 .stream() 和 .forEach(),并且在这两种情况下,它都会在第一批之后消失。

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

我的 collection 中有 200 个文档,下面的代码运行良好。换句话说,无法重现问题。如您所见,我已将批量大小减少到 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);
                }
            }
        });
    }
});

如果您仍然面临同样的问题,我建议将 MongoDB 驱动程序更新到最新版本。由于正在积极开发驱动程序,有时错误会潜入已发布的版本,从而导致奇怪的行为。