这让我很难过。
我有一个独立的(命令行执行的)节点脚本,其目的是遍历大型集合中的所有文档(数十万个),并为每个文档执行一些计算,运行一点其他JS代码,然后使用一些新值更新文档。
根据cursor.each()
的{{3}},一旦我从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,则光标将用尽/清空并关闭。“
但实际所做的是精确打印出101 .
,最后没有X
。
如果我调整批量大小(.find().batchSize(10).each(...
),它会在捞出之前完成相同数量的文件。
那么,为什么只处理第一批?我在某种程度上误读了.each()的文档?它是否与这是一个命令行脚本有关,并且在第二批结果返回之前,整个脚本以某种方式退出,或者什么?如果是这样,我如何确保它实际处理所有结果?
作为一个副节点,我尝试过使用.stream()和.forEach(),在这两种情况下,它都会在第一批之后出现。
更新 嗯,这很有趣。刚尝试连接到我的生产服务器而不是我在localhost上的mongo实例,瞧,它会像它应该的那样贯穿整个集合。服务器正在运行mongodb 3.0.6,我的本地实例是3.2.3。我的节点mongodb驱动程序的版本是2.0.43。
答案 0 :(得分:4)
I have 200 documents in my collection and following code goes well. In other words, couldn't reproduce problem. As you can see I have reduced batch size to 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);
}
}
});
}
});
If you are still facing same issue, I'd suggest to update MongoDB driver to latest version. Since drivers are actively being developed, sometime bugs sneak into released version causing strange behavior.