Home >PHP Framework >Laravel >Please do not sort when using chunkById method!
The following tutorial column will introduce you to Laravel. Please do not sort when using the chunkById method! , I hope it will be helpful to friends in need!
Please do not sort when using the chunkById method
I recently encountered a strange problem when doing development tasks. So I share it with you
Problem Description
Since the data needs to be processed in batches, and the amount of this data is very large, it is unrealistic to take it all out at once and then execute it. Fortunately, It is Laravel that provides us with the chunkById method for us to handle conveniently. The pseudo code is as follows
Student::query() ->where('is_delete', false) ->orderBy('id', 'DESC') ->chunkById(200, function($students) { // 在这里进行逻辑处理 });
At first glance, there is no problem, but when you actually execute the code, you will find that chunkById will only be executed for the first time, and will stop executing for some reason after the second time.
Find the reason
The chunkById code in Laravel’s source code is as follows
public function chunkById($count, callable $callback, $column = null, $alias = null) { $column = is_null($column) ? $this->getModel()->getKeyName() : $column; $alias = is_null($alias) ? $column : $alias; $lastId = null; do { $clone = clone $this; $results = $clone->forPageAfterId($count, $lastId, $column)->get(); $countResults = $results->count(); if ($countResults == 0) { break; } if ($callback($results) === false) { return false; } $lastId = $results->last()->{$alias}; unset($results); } while ($countResults == $count); return true; }
It seems there is no problem, because the while loop is based on $countResults == $count To judge, if we dump these two variables, we will find that the first time they are consistent, the second time the program stops due to inconsistent data.
In the above code, $count is obtained by $results = $clone->forPageAfterId($count, $lastId, $column)->get();,
Continue to view the forPageAfterId method
public function forPageAfterId($perPage = 15, $lastId = 0, $column = 'id') { $this->orders = $this->removeExistingOrdersFor($column); if (! is_null($lastId)) { $this->where($column, '>', $lastId); } return $this->orderBy($column, 'asc') ->take($perPage); }
We can see that the results returned here are arranged in ascending order by orderBy, while our original code is arranged in descending order, which will cause the count to be inconsistent, thus ending chunkById implement.
Solution
Just remove the previous orderBy('id', 'desc').
Student::query() ->where('is_delete', false) ->chunkById(200, function($students) { // 在这里进行逻辑处理 });
Summary
Do not add custom sorting when using chunkById or chunk method in the future
You can grow old by being cool and learn by learning. . .
The above is the detailed content of Please do not sort when using chunkById method!. For more information, please follow other related articles on the PHP Chinese website!