限制雄辩的块

时间:2016-08-19 00:32:53

标签: laravel laravel-5 eloquent

我有一个非常大的结果集要处理,所以我使用chunk()方法来减少作业的内存占用。但是,我只想处理一定数量的总结果,以防止作业运行太长时间。

目前我正在这样做,但它似乎不是一个优雅的解决方案:

$count = 0;
$max = 1000000;
$lists = Lists::whereReady(true);

$lists->chunk(1000, function (Collection $lists) use (&$count, $max) {
    if ($count >= $max)
        return;

    foreach ($lists as $list) {
        if ($count >= $max)
            break;

        $count++;

        // ...do stuff
    }
});

有更简洁的方法吗?

1 个答案:

答案 0 :(得分:6)

截至目前,我不相信。

提交的一些问题和提交请求具有大块尊重先前设置的跳过/限制,但是泰勒已将它们关闭为块大写覆盖这些内容的预期行为。

laravel / internals repo目前有一个open issue,他说他会再看看,但我不认为它在优先级列表中很高。我怀疑这是他会做些什么,但现在可能更容易接受另一个拉请求。

除了一件事,你的解决方案看起来很好。除非您从关闭位置返回chunk(),否则false将最终读取您的整个表格。目前,您只是返回null,因此即使您的“max”设置为1000000,它仍会读取整个表格。如果return false时关闭$count >= $maxchunk()将停止查询数据库。它会导致chunk()本身返回false,但是您的示例代码无论如何都不关心chunk()的返回,所以没关系。

假设您正在使用顺序ID,另一个选项是获取结尾id,然后在您的分块查询中添加一个where子句,以获得id小于id的所有记录最大$max = 1000000; $maxId = Lists::whereReady(true)->skip($max)->take(1)->value('id'); $lists = Lists::whereReady(true)->where('id', '<', $maxId); $lists->chunk(1000, function (Collection $lists) { foreach ($lists as $list) { // ...do stuff } }); 。所以,像:

{{1}}

代码稍微清晰,但它仍然是一个黑客,需要一个额外的查询(以获得最大ID)。