Besoin d'aide ?

Laravel collection filter chunk

Avatar de MourareauMathieu
MourareauMathieu

J'ai un gros souci de performance avec un bout de code qui permet de filtrer les élements de ma collection grace à un calcul de distance GoogleMaps.

Il me faudrait le moyen de charger qu'une partie de la collection tant que $geo_filter->isNotEmpty ! j'ai vraiment besoin d'aide

voici ma collection $arbitres = Licencies::getArbitres($rencontre->dt_rencontre);

voici ma methode getArbitres :

public static function getArbitres($date){


        $licences = Licencies::whereIn('activite_licencie_id' , [24,25,50,80])
            ->where('valid_licence_id' , 3)
            ->where('saison_id' , self::getSaison()->id)
            ->where('dispo' , 1)
            ->whereHas('fonctions')
            ->whereHas('divisions')
            ->whereDoesntHave('rencontreOfficiels', function ($query) use ($date) {
                $query->where('dt_rencontre', $date);
            })->get();

        return $licences;
    }

voici mon bout de code qui prend des plombes car j'ai 100 élements dans ma collection :

for($i=0; $i <= 1200 ; $i+=200){

                        $geo_filter = $arbitres->filter(function ($arbitre) use ($rencontre , $i) {

                            $origin = $arbitre->lb_adresse .' '. $arbitre->lb_ville_naissance .' '. $arbitre->cd_dept_naissance;
                            $destination = $rencontre->stade->adresse_stade .' '. $rencontre->stade->ville_stade .' '. $rencontre->stade->cd_post_stade;

                            $distance = getDistance($origin, $destination);
                            $distance = (float)$distance;

                            if($distance <= $i){
                                return true;
                            }

                            return false;
                        });


                        if ($geo_filter->isNotEmpty()) {
                            $arbitres = $geo_filter;
                            break;
                        }
                    }

voici mon helper getDistance qui gère le process de calcul distance :

function getDistance($origin, $destination){

    $distance = 0;

    $response = \GoogleMaps::load('directions')
        ->setParam([
            'origin'          => $origin,
            'destination'     => $destination,
            'mode' => 'driving' ,
            'language' => 'fr',

        ])->get();

    $parsed_json = (json_decode($response));

    if($parsed_json->status != "NOT_FOUND") {
        $result = $parsed_json->{'routes'}[0]->{'legs'}[0]->{'distance'}->{'text'};
        $a = $result;
        $b = str_replace(" km",'',$a);
        $distance = str_replace(",",'.',$b);
    }

    if(is_numeric($distance)){
        $distance = $distance * 2;
    }


    return $distance;
}
Posté il y a 1 mois
Avatar de bestmomo
bestmomo

Salut,

Je vais peut-être dire une bêtise mais est-ce qu'il ne serait pas possible de procéder à un pré-traitement ? Je m'explique : tu as un certain nombre de stades dont tu connais la localisation, ensuite tu as des arbitres dont tu connais l'adresse. Si tu lançais un calcul complet pour chaque arbitre en fonction de chaque stade pour avoir les distances et que tu renregistres ces distances dans une table. Si c'est faisable, et je ne vois pas trop pourquoi ça ne le serait pas, alors ça va accélérer ton traitement parce que tu n'auras plus le calcul par Maps et tu pourras intégrer la recherche dans ta requête SQL. Ensuite il faudrait évidemment traiter au cas par cas les changements d'adresse, les nouveau stades et les nouveaux arbitres.

Posté il y a 1 mois
Avatar de MourareauMathieu
MourareauMathieu

Excellente idée :) je ferrai toujours un cron ou un truc du genre pour indexer les nouvelles valeurs !!!! merci beaucoup pour l'idée

Posté il y a 1 mois

Vous ne pouvez pas répondre à ce sujet.