Красноречивый кусок () не хватает половины результатов

У меня проблема с методом LARARL ORL Eloquent chunk (). Он пропустил некоторые результаты. Вот тестовый запрос:

$destinataires = Destinataire::where('statut', '<', 3) ->where('tokenized_at', '<', $date_active) ->chunk($this->chunk, function ($destinataires) { foreach($destinataires as $destinataire) { $this->i++; } } echo $this->i; 

Он дает 124838 результатов.

Но :

 $num_dest = Destinataire::where('statut', '<', 3) ->where('tokenized_at', '<', $date_active) ->count(); echo $num_dest; 

дает 249676, поэтому просто ДВАЖДЫ как первый пример кода.

Мой скрипт должен редактировать все соответствующие записи в базе данных. Если я запускаю его несколько раз, он просто раздаёт половину оставшихся записей каждый раз.

Я попытался использовать DB :: table () вместо Модели. Я попытался добавить a>> take (20000), но, похоже, это не учитывается. Я повторил запрос с помощью -> toSql (), и eveything кажется прекрасным (предложение LIMIT добавляется, когда я добавляю параметр -> take ()).

Какие-либо предложения ?

Для тех, кто ищет немного кода, который решает это, здесь вы идете:

 while (Model::where('x', '>', 'y')->count() > 0) { Model::where('x', '>', 'y')->chunk(10, function ($models) { foreach ($models as $model) { $model->delete(); } }); } 

Проблема заключается в удалении / удалении модели, в то время как она отрывается от общей суммы. Включая его в цикл while, вы обязательно получите их все! Этот пример работает при удалении моделей, измените условия в соответствии с вашими потребностями!

У меня была та же проблема – только половина общих результатов была передана функции обратного вызова метода chunk () .

Вот код, который имел проблемы:

 Transaction::whereNull('processed')->chunk(100, function ($transactions) { $transactions->each(function($transaction){ $transaction->process(); }); }); 

Я использовал Laravel 5.4 и сумел решить проблему, заменив метод chunk () на метод cursor () и изменив код соответственно:

 foreach (Transaction::whereNull('processed')->cursor() as $transaction) { $transaction->process(); } 

Несмотря на то, что ответ не касается самой проблемы, он обеспечивает ценное решение.

Представьте, что вы используете метод chunk для удаления всех записей. Таблица имеет 2 000 000 записей, и вы собираетесь удалить их все на 1000 кусков.

 $query->orderBy('id')->chunk(1000, function ($items) { foreach($items as $item) { $item->delete(); } }); 

Он удалит первые 1000 записей, получив первые 1000 записей в таком запросе:

 SELECT * FROM table ORDER BY id LIMIT 0,1000 

И тогда другой запрос из метода chunk:

 SELECT * FROM table ORDER BY id LIMIT 1000,2000 

Наша проблема заключается в том, что мы удаляем 1000 записей, а затем получаем результаты от 1000 до 2000. На самом деле нам не хватает первых 1000 записей, и это означает, что мы не собираемся удалять 1000 записей на первом этапе куска! Этот сценарий будет таким же для других шагов. На каждом этапе мы собираемся пропустить 1000 записей, и именно по этой причине мы не получаем лучший результат в этих ситуациях.

Я сделал пример для удаления, потому что таким образом мы могли бы узнать точное поведение метода chunk.

Я не мог решить эту проблему, мне пришлось перестать использовать chunk ().

Вот что я сделал, чтобы использовать простой старый PDO. Остерегайтесь одной вещи: переменная $ row, заполненная PDO, является (obvisouly) не Eloquent Model, а вместо этого просто объектом stdClass.

 $pdo = \DB::connection()->getPdo(); $query = "SELECT * FROM $myModelTable WHERE ...."; $stmt = $pdo->prepare($query); $stmt->execute(); while ($row = $stmt->fetchObject()) { // $row is stdClass instead of MyModel } 

Надеюсь это поможет. Я с нетерпением жду некоторой информации о случайном странном поведении этого куска.