迭代大型MongoDB集合而不会耗尽内存

时间:2016-08-18 15:51:30

标签: php mongodb hhvm

我有一个想要迭代的大型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

感谢您的帮助。

1 个答案:

答案 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的文档?