简体   繁体   English

在laravel 5.8中优化请求

[英]Optimize request in laravel 5.8

I have been stuck since yesterday on a request that I can not solve. 自昨天以来我一直被困在一个我无法解决的请求上。 I make a site to manage an abandoned dog shelter. 我建立了一个管理废弃狗舍的网站。 Dogs must be vaccinated: 狗必须接种疫苗:

  • A first time in their life then a month later for a reminder 他们生命中的第一次,然后一个月后提醒
  • Then once a year 然后一年一次

So I am looking for from my table "animals" and my table "soinsveto" to list all dogs that have not had vaccines for over a year or if it is their first vaccine since more a month. 因此,我正在寻找我的餐桌“动物”和我的餐桌“soinsveto”,列出所有未接种疫苗超过一年的狗,或者是一个月以来它们是第一种疫苗。

The goal is to put an alert in the administration interface that will say "attention this dog is not vaccinated, it should have been before the ...) 目标是在管理界面中发出警报,说“注意这只狗没有接种疫苗,它本应该在...之前”

my table "animals" 我的桌子“动物”

id | name |

My table "soinveto" (typesoin_id = 1 if it is the first vaccine and there is a delay of one month before the next vaccine and 2 if the vaccine has a period of one year 我的表“soinveto”(如果它是第一种疫苗,则typesoin_id = 1,并且在下一次疫苗之前有一个月的延迟,如果疫苗的期限为一年则延迟2次

id | typesoin_id | animal_id | datedusoin

Animal model 动物模型

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

soinveto model soinveto模型

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

I am looking to select: 我想选择:

  • all the animals ("table animals") with the single last vaccination ("soinsvetos" table with typesoin_id = 1 or 2) by date ("datedusoin" field). 具有单次最后一次接种的所有动物(“表动物”)(具有typesoin_id = 1或2的“soinsvetos”表)按日期(“datedusoin”字段)。 I prefer to do with the dates because it is possible that the users seize vaccines in the disorder. 我更喜欢使用日期,因为用户可能会在疾病中抓住疫苗。 Work on the "id" risk of Do not walk. 处理“id”风险不要走路。

  • Then if "typesoin_id" is 1 I check that there is not more than one month with the date of today and if it is 2 that there is not more than one year. 然后,如果“typesoin_id”为1,我检查今天的日期不超过一个月,如果是2则不超过一年。

I found a solution that works but is not optimized at all as you can see : 我找到了一个有效的解决方案但根本没有进行优化,你可以看到:

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);


}

With my version all the animals are loaded which makes a huge number of sql requests. 在我的版本中,所有动物都被加载,这会产生大量的sql请求。 I can not find any solutions to make this happen. 我无法找到任何解决方案来实现这一目标。 I tried a lot of things but I can not get everything together in a single optimized query 我尝试了很多东西但是我无法在一个优化的查询中将所有内容整合在一起

Following up on my comments to the question, I suggest you rewrite your foreach statement to the code below. 继续我对这个问题的评论,我建议你将foreach语句重写为下面的代码。 It uses the with function to eager load the soinsvetos relationship in all animals so that you do not end up with the N+1 problem. 它使用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,
    ];

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM