2012-12-05 49 views
2

這是一個例子來複制我的問題:的MongoDB的NodeJS司機沒有返回超過10行

我填充我的收藏與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}); 

然後,我有FO使用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不是空 (應該有周圍333000)

我敢肯定的問題是這樣的MongoDB緩存,但我不知道我該如何解決這個問題?

+1

你不只是增加你的人口代碼100000個文檔?也許這只是一個錯字。無論如何,在帶有333,000個文檔的光標上調用「toArray」正在尋找麻煩。您應該對結果進行流式處理或迭代,而不是將它們轉儲到大量數組中。 – JohnnyHK

+0

修正了錯字;-) – Alex

+0

我認爲這可能是問題所在......你有一個如何流/迭代的例子嗎? – Alex

回答

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!'); 
}); 
+0

非常好...它確實有幫助.. –

+0

每個流和每個流都返回一個文檔是否有區別?除了暫停和恢復流。謝謝約翰尼。 – Maziyar

6

您需要設置批量大小,然後流或重複的結果,否則mongo驅動程序將所有內容粘貼到內存中。

也是{'_id':1}氣味腥,這大概應該是{fields: {'_id' : 1}}

所以結果在您的情況將是:

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