【问题标题】:MongoDB nodejs driver not returning more than 100000 rowsMongoDB nodejs驱动程序不返回超过100000行
【发布时间】:2012-12-06 01:12:15
【问题描述】:

这是复制我的问题的示例:

我用 100 万个这样的文档填充我的收藏:

for(i=1; i<=1000000; i++){
if(i%3===0)
     db.numbers.insert({_id:i, stuff:"Some data", signUpDate: new Date()});
else
     db.numbers.insert({_id:i, stuff:"Some data"});
}

所以,每 3 个文档都有一个 signUpDate

我创建了以下索引:

db.numbers.ensureIndex({"signUpDate" : 1});

然后,我有以下使用 nodejs 的非常小的应用程序:

var Db = require('mongodb').Db
, Connection = require('mongodb').Connection
, Server = require('mongodb').Server
, format = require('util').format;

var host = 'localhost';
var port = Connection.DEFAULT_PORT;

console.log("Connecting to " + host + ":" + port);

Db.connect(format("mongodb://%s:%s/test?w=1", host, port), function(err, db) {
        var collection = db.collection('numbers');

        collection.find({'signedUp': true}, {'_id':1}).limit(100000).toArray(function(err, docs){
                console.log(docs.length)
        });
});

这很好用。

但是,如果我删除了 .limit(100000),服务器会坐在那里并且永远不会响应。

简而言之,我要做的就是返回一个 _id 列表,其中 signUpDate 不为空 (应该有 333,000 左右)

我很确定问题出在 mongodb 缓存的方式上,但我不确定如何解决这个问题?

【问题讨论】:

  • 你不是只在人口代码中添加了 100,000 个文档吗?也许这只是一个错字。无论如何,在有 333,000 个文档的游标上调用 toArray 是在找麻烦。您应该对结果进行流式传输或迭代,而不是仅仅将它们转储到一个庞大的数组中。
  • 我认为这可能是问题所在...您有如何流式传输/迭代的示例吗?
  • 好的,我将其发布为答案。

标签: node.js mongodb node-mongodb-native


【解决方案1】:

您不应该在这样的大型结果集上调用toArray。相反,要么:

使用each 迭代结果:

collection.find({'signedUp': true}, {'_id':1}).each(function(err, doc){
    if (doc) {
        console.log(doc);
    } else {
        console.log('All done!');
    }
});

stream结果:

var stream = collection.find({'signedUp': true}, {'_id':1}).stream();
stream.on('data', function(doc) {
    console.log(doc);
});
stream.on('close', function() {
    console.log('All done!');
});

【讨论】:

  • 每个和流之间有什么区别,因为它们都一次返回一个文档?除了在流中暂停和恢复。谢谢约翰尼。
【解决方案2】:

您需要设置批处理大小,然后流式传输或迭代结果,否则 mongo 驱动程序会将所有内容都粘贴到内存中。

还有{'_id':1}有腥味,应该是{fields: {'_id' : 1}}

所以你的情况的结果是:

collection.find({'signedUp': true}, {batchSize: 1000, fields: {'_id' : 1}}).each(function(err, item) { 
    do something with item
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-29
    • 1970-01-01
    • 1970-01-01
    • 2020-06-18
    • 1970-01-01
    • 2016-03-13
    相关资源
    最近更新 更多