我正在尝试通过Python查询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 :(得分: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进行测试,结果总是相同)。
答案 1 :(得分:0)
好的,我在MongoDB的源代码中找到了一行,它清除了所有使用次数超过10次的JavaScripts。因此,如果不需要对数据库服务器进行任何更改,则需要多次查询数据库,并通过在skip()和limit()函数的帮助下选择项目数量来向客户端发送批量数据。这种工作速度惊人。谢谢你的帮助。