Laravel |Специальная проверка большого количества данных - PullRequest
0 голосов
/ 19 сентября 2019

Проверка данных (1 - 10000 возможных строк)

Поэтому, чтобы дать некоторый контекст, я создаю веб-интерфейс отображения для сопоставления других форматов данных с нашим форматом.

Проблема

Взятие массива данных и массива форматов, подобных этому:

$vehicle = [
    'cost' => '$159',
    'reconditioning' => '$140'
];

$formats = [
    'cost' => 'integer',
    'reconditioning' => 'integer'
];

И проверка всех полей на несоответствия с нашей структурой данных, например "total_cost "будет ошибкой в ​​данных, поскольку в них есть нечисловой символ.Выходные данные проверки должны отображать ошибку для каждого отдельного поля, как показано ниже (истинное значение означает, что в этом поле есть ошибка):

$vehicle_errors = [
    'total_cost' => true, 
    're_condition' => true
];

Что после проверки я отображаю поля, которые имелиошибки для их исправления пользователем.

Мне все это удалось, но я использовал циклы for и случай переключения для проверки каждого отдельного поля, это становится проблемой, когда мы получаем более несколькихтысячи транспортных средств.

То, что я пробовал

Я пытался с помощью for-loop сделать это успешно, но php потребовал, чтобы я увеличил max_input_vars до уровня, который я бы хотелпостарайтесь избежать, потому что эта операция облагает налогом мой сервер.Я также попробовал проверку Laravels, которая не дала мне желаемого результата, а также имела ту же проблему, что и при использовании for-loop, с ошибкой php.

Возможные решения

Я знаю, что тамспособ проверить данные в таблице MySQL и получить вывод, аналогичный тому, что мне нужно, это решило бы мою проблему из-за использования ресурсов сервера MySQL, но я не имею ни малейшего представления о том, как это сделать, и не смог найтичто-нибудь в сети на эту тему.

Ответы [ 2 ]

0 голосов
/ 24 сентября 2019

Похоже, что ваша основная проблема в этом случае заключается в том, что массив данных слишком велик для загрузки в память за один раз, поэтому ваше приложение падает, когда массив становится слишком большим.

Генераторы были добавлены в PHP для решения этой проблемы.Они позволяют перебирать набор данных без необходимости хранить все это в памяти, что делает его более практичным для работы с очень большими наборами данных.Однако синтаксис может быть немного громоздким.

Как это происходит, недавно выпущенный Laravel 6 предлагает решение этой проблемы в виде ленивых коллекций .Они используют генераторы, но предоставляют более дружественный интерфейс, так что вы можете легко перебирать очень большие наборы данных, не используя слишком много памяти.Вот пример его использования, взятый из https://www.magutti.com/blog/laravel-lazy-collections:

use App\Project;
use Illuminate\Support\LazyCollection;


Route::get('/', function () {

    LazyCollection::make(function () {
        // project.csv  with 300.000 rows
        $filePath = storage_path('app/public/project.csv');
        $handle = fopen($filePath, 'r');
        while ($line = fgetcsv($handle)) {
            yield $line;
        }
    })
        ->chunk(10000) //split in chunk to reduce the number of queries
        ->each(function ($lines) {

            $list = [];
            foreach ($lines as $line) {
                if (isset($line[1])) {
                    $list[] = [
                        'name' => $line[1],
                        'email' => $line[2],
                        'status_id' => $line[3]
                    ];
                }
            }
            // insert 10000 rows in one shot
            Project::insert($list);

        });
    /* display memory usage */
    echo number_format(memory_get_peak_usage() / 1048576, 2) . ' MB';
});

Eloquent ORM теперь также возвращает отложенную коллекцию при вызове метода cursor(), так что вы можете использовать его для обработки очень больших наборовданных, возвращаемых из базы данных, а также.Все это достижимо только с помощью генераторов, но ленивые коллекции обеспечивают более простой и читаемый способ сделать это.

0 голосов
/ 19 сентября 2019

Я думаю, что вы хотите использовать чанк.

DB::table('formats')->chunk(100, function($formats)
{
    foreach ($formats as $format)
    {
        //perform validation
    }
});

Вы также, вероятно, захотите сделать это в команде, а не в запросе, чтобы избежать тайм-аутов и прочего.В зависимости от вашей настройки вы также можете создавать задания в очереди для каждого элемента или только те, которые не проходят проверку, если исправление интенсивно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...