【问题标题】:Iterating over a big MongoDB collection without running out of memory迭代一个大的 MongoDB 集合而不会耗尽内存
【发布时间】:2016-12-25 15:27:33
【问题描述】:

我有一个大的 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);
}

这看起来很尴尬。迭代器的全部意义在于不必这样做。有没有更好的办法?

我正在使用带有mongofill 的 hhvm 3.12。

感谢您的帮助。

【问题讨论】:

    标签: php mongodb hhvm


    【解决方案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-&gt;documents。 没有什么可以清除此文档集合。 您可以尝试实现一个迭代,在获取$this-&gt;documents 的文档之后删除它们吗?

    【讨论】:

    • 这看起来也是一个你应该直接在 GitHub 上向 mongofill 报告的问题 :)
    猜你喜欢
    • 1970-01-01
    • 2021-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-07
    • 2011-04-05
    • 1970-01-01
    相关资源
    最近更新 更多