2013-03-01 3 views
0

Я пытаюсь запросить большой набор результатов от MongoDB над Python. Я делаю это через 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

+0

Можете ли вы прояснить, что вы хотели бы сделать с вашей доходностью? Если целью является выполнение операции партиями, вы можете сохранить счетчик записей, которые вы выбрали для массива. Когда вы достигнете размера партии, вы затем будете работать с текущим набором записей, а затем очистите массив после. –

+0

Благодарим вас за помощь. Я хотел бы сделать сложный запрос на стороне сервера и получить все результаты для работы с python-side, впоследствии. Если я получу вас правильно, можно было бы работать с небольшими массивами на стороне сервера или дать одному из них обратно в результате, чтобы потребовалось несколько запросов. Я хотел бы обработать все результаты на стороне клиента и, таким образом, вернуть результаты, пакет для партии. – 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 записей. И со стороны 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? Проблема не зависит от объема (тестируется с 10, 100, 1000, 10000 и всегда совпадает с результатом).

0

Хорошо, я нашел строку в исходном коде MongoDB, которая очищает все Java-скрипты, которые используются более 10 раз. Поэтому, если никаких изменений на сервере базы данных не требуется, необходимо несколько раз запрашивать базу данных и отправлять пакеты клиенту, выбирая количество элементов с помощью функций skip() и limit(). Это работает на удивление быстро. Спасибо за вашу помощь.

Смежные вопросы