更新:我已将此范围缩小到看似不同的问题,因此提出了另一个问题here。
=======
我在localhost上运行了一个mongoDB实例,其中包含两个集合,“mydocs
”(其中包含约12,000个文档)和“mydoctypes
”(其中只有7个文档)。 / p>
我有一个独立的NodeJS脚本,它获取与数据库的连接,然后触发以下内容:
myDb.collection('mydoctypes').find().toArray(function(err, results) {
console.log("Got results.");
if (err) {
console.log("err: " + err);
} else {
console.log("Got doctypes: " + results.length);
}
});
该脚本的输出是:
Got results.
Got doctypes: 7
如果我修改相同的脚本来代替访问'mydocs'集合:
myDb.collection('mydocs').find().toArray(function(err, results) {
console.log("Got results.");
if (err) {
console.log("err: " + err);
} else {
console.log("Got docs: " + results.length);
}
});
我根本没有输出。显然,回调永远不会被解雇。
== UPDATE ==
所以看起来问题可能是太多文件导致toArray()耗尽RAM。
现在,我正在使用.each()进行迭代,但有一个不同的问题:每个()只运行第一批(无论我将batchSize设置为),并且从不加载任何更多的文档。代码是这样的:
myDb.collection('mydocs').find().batchSize(50).each(function(err, item) {
if (item != null) {
process.stdout.write(".");
}
}
答案 0 :(得分:0)
确实如注释中所见,默认mongodb
驱动程序为nodejs
返回游标,默认光标在触发时有~101个文档或大约1 MB批量大小,您可以使用batchSize
功能。但是为了迭代您的集合,您应该将其流式传输如下:
MongoClient.connect('mongodb://localhost:27017/mydb', function(err, db) {
var cursor = db.collection('mycollection').find();
cursor.forEach(
function(doc) {
console.log(doc);
},
function(err) {
if (err) {
console.error(err);
} else {
//cursor has exausted, no more docs to iterate exit
return db.close();
}
});
});
应用于游标的forEach
方法不是来自Arrays的javascript默认方法,它有两个回调(cb(doc)将为每个文档迭代,第二个是cb(err)wich将捕获错误或光标耗尽。
您可以使用投影来降低数据量cursor.project({title: 1, name: 1})
,这将显着减少使用的内存量。