Оптимизировать запрос в laravel 5.8 - PullRequest
0 голосов
/ 22 апреля 2019

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

  • Первый раз в жизни, затем месяц спустя для напоминания
  • Затем один раз в год

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

Цель состоит в том, чтобы поставитьоповещение в интерфейсе администрации, в котором будет сказано: «Внимание, эта собака не привита, она должна была быть до ...»

мой стол «животные»

id | name |

мой стол »soinveto"(typesoin_id = 1, если это первая вакцина и имеется задержка в один месяц перед следующей вакциной, и 2, если вакцина имеет период в один год

id | typesoin_id | animal_id | datedusoin

Модель животного

public function soinsvetos() {
    return $this->hasMany(Soinsveto::class, 'animal_id');
}

soinveto модель

public function animal()
{
    return $this->belongsTo(Animal::class, 'animal_id')->withTrashed();
}

Я хочу выбрать:

  • всех животных ("столовых животных") с последней последней вакцинацией ("soinsvetos""таблица с typesoin_id = 1 или 2) по дате (поле" datedusoin "). Я предпочитаюделать с датами, потому что вполне возможно, что пользователи забирают вакцины при расстройстве.Работайте с риском "id" Не ходите.

  • Тогда, если "typesoin_id" равен 1, я проверяю, что дата сегодняшнего дня не превышает одного месяца, и если2, что не более одного года.

Я нашел решение, которое работает, но не оптимизируется вообще, как вы можете видеть:

public function compose(View $view)
{

    foreach (\App\Animal::get()
                 ->all() as $animal) {

        $soins = \App\Soinsveto::with('typesoin')
            ->where('animal_id', $animal->id)
            ->where(function ($q) { /// 1 = primovaccin et 2 = vaccins annuels
                $q->where('typesoin_id', '=', '2')
                    ->orWhere('typesoin_id', '=', '1');
            })
            ->orderBy('datedusoin', 'desc')
            ->get()
            ->first();
        if ($soins) {

            if ($soins->typesoin_id == '1' && $soins->datedusoin < Carbon::now()->subMonths(1)) {
                $crudFieldValue = Carbon::parse($soins->getOriginal('datedusoin'))->addyear(1)->toDateString();

            }
            if ($soins->typesoin_id == '2' && $soins->datedusoin < Carbon::now()->subYears(1)) {
                $crudFieldValue = Carbon::parse($soins->getOriginal('datedusoin'))->addyear(1)->toDateString();

            }

        }
        $notif[] = [
            'title' => $soins->typesoin->nomsoin,
            'start' => $crudFieldValue,
            'nomanimal' => $animal->nom,
        ];
    }
    $view->with('notif', $notif);


}

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

1 Ответ

0 голосов
/ 22 апреля 2019

Следуя моим комментариям к вопросу, я предлагаю вам переписать выражение foreach в приведенном ниже коде.Он использует функцию with для загрузки отношения soinsvetos у всех животных, чтобы вы не столкнулись с проблемой N + 1.

foreach (\App\Animal::with('soinsvetos')->get() as $animal) {

    $soins = $animal->soinsvetos
                    ->filter(function ($soinsveto) {
                        /// 1 = primovaccin et 2 = vaccins annuels
                        return $soinsveto->typesoin_id == 1 || $soinsveto->typesoin_id == 2;
                    })
                    ->sortBy('datedusoin', 'desc')
                    ->first();

    if ($soins) {
        if ($soins->typesoin_id == '1' && $soins->datedusoin < Carbon::now()->subMonths(1)) {
            $crudFieldValue = Carbon::parse($soins->getOriginal('datedusoin'))->addyear(1)->toDateString();
        }
        if ($soins->typesoin_id == '2' && $soins->datedusoin < Carbon::now()->subYears(1)) {
            $crudFieldValue = Carbon::parse($soins->getOriginal('datedusoin'))->addyear(1)->toDateString();
        }
    }

    $notif[] = [
        'title' => $soins->typesoin->nomsoin,
        'start' => $crudFieldValue,
        'nomanimal' => $animal->nom,
    ];

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