【问题标题】:MongoDB JavaScript Yield large set of resultsMongoDB JavaScript 产生大量结果
【发布时间】:2013-02-16 06:04:58
【问题描述】:

我正在尝试通过 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;

现在,我遇到了问题,结果数组变得非常(太大)并且超出了内存。有没有办法产生结果而不是将它们推入数组?

【问题讨论】:

  • 使用next 代替forEach?一次只做一个结果。
  • 您能否说明您希望通过产量实现什么目标?如果目标是批量执行操作,您可以保留已推送到数组的记录的计数器。当达到批量大小时,您将对当前记录集进行操作,然后清除数组。
  • 感谢您的帮助。我想在服务器端做一个复杂的查询,然后让所有结果在 python 端使用。如果我说得对,那么只能在服务器端使用小型阵列或将其中一个返回,这样就需要多个查询。我想在客户端处理所有结果,因此将结果逐批返回。

标签: javascript python mongodb yield


【解决方案1】:

好吧,我想我知道你的意思了。我创建了如下结构:

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 端评估注意到的脚本,然后我执行以下操作:

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 进行测试,结果始终相同)。

【讨论】:

    【解决方案2】:

    好的,我在MongoDB的源代码中找到了一行,它清除了所有使用超过10次的JavaScript。因此,如果不希望对数据库服务器进行任何更改,则需要多次查询数据库并借助 skip() 和 limit() 函数通过选择项目数量来向客户端发送批量。这工作得非常快。感谢您的帮助。

    【讨论】:

      猜你喜欢
      • 2020-05-08
      • 1970-01-01
      • 2017-10-09
      • 1970-01-01
      • 2014-08-06
      • 1970-01-01
      • 1970-01-01
      • 2021-08-15
      • 1970-01-01
      相关资源
      最近更新 更多