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

Ale*_*lex 2 mongodb node.js 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"});
}
Run Code Online (Sandbox Code Playgroud)

因此,每个第3个文档都有一个signUpDate

我创建了以下索引:

db.numbers.ensureIndex({"signUpDate" : 1});
Run Code Online (Sandbox Code Playgroud)

然后,我使用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)
        });
});
Run Code Online (Sandbox Code Playgroud)

这很好用.

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

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

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

Joh*_*yHK 7

你不应该调用toArray像这样的大型结果集.相反,要么:

使用each以下方法迭代结果:

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

流式传输结果:

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!');
});
Run Code Online (Sandbox Code Playgroud)


sou*_*eck 6

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

{'_id':1}有点腥味,它可能应该是{fields: {'_id' : 1}}

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

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