2013-03-01 32 views
0

我試圖通過Python從MongoDB查詢一大組結果。我通過JavaScript來做到這一點,因爲我想在樹狀結構中得到像孫子一樣的東西。我的代碼如下所示:MongoDB JavaScript產生大量結果

col = db.getCollection(...) 
var res = new Array(); 
col.find({ "type" : ["example"] }).forEach(
    function(entry) 
    { 
    v1 = col.find({"_id" : entry["..."]}) 
    ... (walk through the structure) ... 
    vn = ... 
    res.push([v1["_id"], vn["data"]]); 
    } 
);   
return res; 

現在,我遇到了問題,結果數組變得非常(太)大,內存超出。有沒有辦法,爲了得到結果而不是將它們推入數組?

+0

使用'next'而不是'forEach'?一次做一個結果。 – Halcyon 2013-03-01 16:54:35

+0

你能澄清你想用你的收益完成什麼嗎?如果目標是批量執行操作,則可以保留已推送到數組的記錄的計數器。當您達到批量大小時,您將在當前記錄集上進行操作,然後清除該數組。 – 2013-03-01 18:04:33

+0

謝謝你的幫助。我想在服務器端做一個複雜的查詢,然後在python端獲得所有結果。如果我找到了正確的答案,那麼只能在服務器端使用小數組,或者讓其中一個返回,以便需要多個查詢。我想在客戶端處理所有結果,並將結果返回給批處理。 – user2124362 2013-03-04 07:54:51

回答

0

好吧,我想我知道,你的意思。我創建瞭如下結構:

var bulksize = 1000; 
var col = db.getCollection("..");  
var queryRes = col.find({ ... }) 

process = function(entity) { ... } 

nextEntries = function() 
{ 
    var res = new Array(); 
    for(var i=0; i<bulksize; i++) 
    {    
    if(hasNext()) 
     res.push(process(queryRes.next())); 
    else 
     break; 
    } 
    return res; 
} 

hasNext = function() 
{ 
    return queryRes.hasNext(); 
} 

該腳本將結果分成1000個條目。而從Python端EVAL著名腳本,然後我做了以下內容:

while database.eval('hasNext()'): 
    print "test" 
    for res in database.eval('return nextEntries()'): 
     doSth(res) 

有趣的是,該控制檯總是說:

test 
test 
test 
test 
test 
test 

然後我得到的錯誤:

pymongo.errors.OperationFailure: command SON([('$eval', Code('return nextEntries()', {})), ('args',())]) failed: invoke failed: JS Error: ReferenceError: nextEntries is not defined nofile_a:0 

這意味着,nextEntries()的第一次調用起作用,但函數不再存在。難道,MongoDB會做一些清理JavaScript緩存的工作嗎?問題不取決於bulksize(用10,100,1000,10000測試,結果總是一樣)。

0

好的,我在MongoDB的源代碼中找到了一行,它清除了所有使用超過10次的JavaScript。因此,如果不需要數據庫服務器上的任何更改,則需要多次查詢數據庫並通過在skip()和limit()函數的幫助下選擇項目數來向客戶端發送批量。這項工作的速度驚人地快。謝謝你的幫助。

相關問題