我有一个非常大的结果集要处理,所以我使用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
}
});
有更简洁的方法吗?
答案 0 :(得分:6)
截至目前,我不相信。
提交的一些问题和提交请求具有大块尊重先前设置的跳过/限制,但是泰勒已将它们关闭为块大写覆盖这些内容的预期行为。
laravel / internals repo目前有一个open issue,他说他会再看看,但我不认为它在优先级列表中很高。我怀疑这是他会做些什么,但现在可能更容易接受另一个拉请求。
除了一件事,你的解决方案看起来很好。除非您从关闭位置返回chunk()
,否则false
将最终读取您的整个表格。目前,您只是返回null
,因此即使您的“max”设置为1000000,它仍会读取整个表格。如果return false
时关闭$count >= $max
,chunk()
将停止查询数据库。它会导致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)。