2013-03-01 2 views
0

MongoDB에서 많은 결과를 파이썬으로 쿼리하려고합니다. 자바 스크립트를 통해이 작업을 수행합니다. 왜냐하면 나무와 비슷한 구조로 손주와 같은 것을 얻고 싶기 때문입니다. 내 코드는 다음과 같습니다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

'forEach' 대신'next'를 사용 하시겠습니까? 한 번에 하나의 결과 만 수행하십시오. – Halcyon

+0

수익률로 달성하고자하는 것을 명확히 할 수 있습니까? 일괄 적으로 작업을 수행하는 것이 목표 인 경우 밀어 넣은 레코드 카운터를 배열에 보관할 수 있습니다. 배치 크기에 도달하면 현재 레코드 세트에서 작업 한 후 배열을 지 웁니다. –

+0

도움 주셔서 감사합니다. 나는 서버 측에서 복잡한 쿼리를 수행하고 파이썬 측에서 모든 결과를 얻고 싶다. 내가 맞으면 서버 측의 작은 배열로 작업하거나 그 중 하나를 결과로 돌려 주어 여러 개의 쿼리가 필요할 것입니다. 클라이언트 측에서 모든 결과를 처리하고 결과를 배치에 배치하고 싶습니다. – user2124362

답변

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 개의 항목으로 나눕니다. 그리고 파이썬 저명한 스크립트 평가 사이드에서 내가 다음을 수행하십시오

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

흥미로운 것은 콘솔은 항상 말한다 것을 :

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

test 
test 
test 
test 
test 
test 

그런 다음 나는 오류

이것은 nextEntries()의 첫 번째 호출이 작동하지만 더 이상 그 함수가 존재하지 않는다는 것을 의미합니다. MongoDB가 JavaScript 캐시를 비우는 것과 같은 작업을 수행 할 수 있습니까? 문제는 bulksize (10, 100, 1000, 10000으로 테스트되었고 항상 같은 결과)에 의존하지 않습니다.

0

좋아, 나는 MongoDB의 소스 코드에서 10 번 이상 사용 된 모든 JavaScript를 지우는 줄을 발견했다. 따라서 데이터베이스 서버를 변경하지 않으려면 데이터베이스를 여러 번 쿼리하고 skip() 및 limit() 함수를 사용하여 항목 수를 선택하여 대량을 클라이언트로 보내야합니다. 놀랍게도 빠르게 작동합니다. 당신의 도움을 주셔서 감사합니다.