Home > PHP Framework > Laravel > Please do not sort when using chunkById method!

Please do not sort when using chunkById method!

藏色散人
Release: 2020-11-04 14:25:40
forward
3891 people have browsed it

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 chunkById method!

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) {
            // 在这里进行逻辑处理
    });
Copy after login

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;
    }
Copy after login

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);
}
Copy after login

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) {
            // 在这里进行逻辑处理
    });
Copy after login

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!

Related labels:
source:learnku.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template