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 驱动程序更新到最新版本。由于正在积极开发驱动程序,有时错误会潜入已发布的版本,从而导致奇怪的行为。
这让我难住了。
我有一个独立的(命令行执行的)节点脚本,其目的是遍历大型集合(数十万个)中的所有文档,并对每个文档执行一些计算,运行 一些额外的 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 驱动程序更新到最新版本。由于正在积极开发驱动程序,有时错误会潜入已发布的版本,从而导致奇怪的行为。