在 运行 内存不足的情况下迭代一个大的 MongoDB 集合
Iterating over a big MongoDB collection without running out of memory
我有一个很大的 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。
感谢您的帮助。
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
的文档后删除它们吗?
我有一个很大的 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。
感谢您的帮助。
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
的文档后删除它们吗?