MongoDB nodejs驱动程序不返回超过100000行

时间:2012-12-05 14:23:35

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

这是复制我的问题的一个例子:

我用这样的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不为null (应该有333,000左右)

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

2 个答案:

答案 0 :(得分:7)

您不应该像这样在大型结果集上调用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!');
});

答案 1 :(得分:6)

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

同样{'_id':1}闻起来很腥,可能应该是{fields: {'_id' : 1}}

因此,您的案例结果将是:

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