Node + MongoDB:coll.find()。toArray(cb)适用于集合A,但从不为集合B触发cb?

时间:2016-04-01 18:35:36

标签: node.js mongodb mongoskin

更新:我已将此范围缩小到看似不同的问题,因此提出了另一个问题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(".");
    }
}

1 个答案:

答案 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}),这将显着减少使用的内存量。