我有一个想要迭代的大型Mongo集合,所以我做了类似的事情:
$cursor = $mongo->my_big_collection->find([]);
foreach ($cursor as $doc)
do_something();
但我最终耗尽了记忆力。我希望光标在处理完每个文档后释放内存。为什么不是这样的?
我尝试在循环结束时调用unset($doc)
,但这没有帮助。
现在我必须做这样的事情来解决这个问题(按批处理文档并在每批后调用光标上的unset()
):
for ($skip = 0; true; $skip += 1000)
{
$cursor = $mongo->my_big_collection->find()->skip($skip)->limit(1000);
if (!$cursor->hasNext())
break;
foreach ($cursor as $doc)
do_something();
unset($cursor);
}
这看起来很尴尬。迭代器的重点是不必这样做。还有更好的方法吗?
我正在使用hhvm 3.12和mongofill。
感谢您的帮助。
答案 0 :(得分:1)
<强> MongoCursor.php 强>
/**
* Advances the cursor to the next result
*
* @return void - NULL.
*/
public function next()
{
$this->doQuery();
$this->fetchMoreDocumentsIfNeeded(); // <<< add documents to $this->documents
$this->currKey++;
}
/**
* Return the next object to which this cursor points, and advance the
* cursor
*
* @return array - Returns the next object.
*/
public function getNext()
{
$this->next();
return $this->current();
}
当您遍历游标时,它将在游标中存储所有文档$this->documents
。
没有清楚这个文件集。
您可以尝试实现一个迭代,在获取它们之后删除$this->documents
的文档?