I have a method of a class that I extend from ELOQUENT that has to process very large collections of the order of more than 800,000 items and I have realized that it eventually causes some difficulties in the service, so I decided according to the advice of the documentation of Laravel, use chunk() method from QueryBuilder. The process is to read the existing entries in a certain date range and then calculate averages in time subdivisions of the entire collection, to display in a behavior graph. The problem is that the chunk() method perfectly processes each chunk calculating the averages of each input segment but I can't get it to return those averages, I can print them from an "echo" but as by default it does a loop iterating between each chunk of the collection, at the end it only returns a "
public static function gghh($campo, $marca = [], $corte=5000)
{
$ini = isset($marca["ini"]) ? $marca["ini"] : Carbon::now()->subDay()->format('Y-m-d');
$fin = isset($marca["fin"]) ? $marca["fin"] : Carbon::now()->format('Y-m-d');
return self::whereBetween("fecha", [$ini, $fin])->chunk($corte,function ($regs) use ($campo){
//echo $regs->avg($campo)."<br />";
//echo $regs->first()->fecha."<br />";
if(!isset($trozos))
{
$trozos = [];
}
array_push($trozos, ["dato" => $regs->avg($campo), "fecha" => $regs->first()->fecha]);
return $trozos
});
}
I know that the process is done correctly because if I remove the comments from the two "echoes", the values are displayed correctly, but I need these same values to be returned to me for a later process. As it is now shown, the method only returns a boolean value (TRUE). Any ideas to obtain something like the Array that follows?
[
["dato"=>145.58, "fecha"=>"2020-08-12"],
["dato"=>128.89, "fecha"=>"2020-09-12"],
["dato"=>132.14, "fecha"=>"2020-10-12"],
["dato"=>136.62, "fecha"=>"2020-11-12"],
...
]
It's a scope issue. If
$trozos
it doesn't exist and you declare it inside the loop, it doesn't exist outside of the loop, nor in the next loop. The methodchunk
is not onemap
that you can return from, but only oneeach
in easy installments.The only effect it has
return $trozos
is that if in any iteration this variable is falsy it is assumed that you don't want to process the batches any further.I would try:
Note that I pass it
$trozos
by reference, since if I pass it as a value, it would be expected not to affect its value in the upper scope.