Solution à l'échec du tri de Laravel : 1. Interrogez les données via "$query->whereIn(...)" ; 2. Filtrez les données via le filtre ; 3. Définissez les données triées sur "$data = $scoutModelsLists;".
L'environnement d'exploitation de cet article : système Windows 7, Laravel version 5.8, ordinateur Dell G3.
Comment résoudre le problème d'échec du tri de Laravel ?
Laravel 5.8+scout7.0 utilisant la solution d'échec de tri orderBy
Récemment, lors de l'utilisation d'elasticSearch6.2.4 pour effectuer des recherches, j'ai trouvé que le champ de tri n'est pas valide, je vais donc l'enregistrer ici
Jetons un coup d'œil à la solution d'abord, pas grand chose à dire Dites, allez directement au code
$list = Article::search($words)->orderBy('created_at','desc')->paginateRaw(10)->toArray(); $results = $list['data']; if ($results['hits']['total'] === 0) { return $this->model->newCollection(); } $builder =new Builder(new static(),$this->model->newModelQuery()); $keys = collect($results['hits']['hits'])->pluck('_id')->values()->all(); $query = $this->newQuery(); if ($builder->queryCallback) { call_user_func($builder->queryCallback, $query); } //查询数据 $scoutModelsLists = $query->whereIn( $this->model->qualifyColumn($this->model->getKeyName()), $keys )->orderBy('created_at','desc')->get(); //过滤数据 $scoutModelsLists->filter(function () use ($keys) { return in_array($this->model->getKey(), $keys); }); //这里为最终排序好的数据 $data = $scoutModelsLists;
Analyse du problème
L'instruction de requête originale utilisée est
$list = Article::search($words)->orderBy('created_at','desc')->paginate(10)->toArray();
Bien que l'instruction de requête ci-dessus définisse le champ de tri, elle n'est pas triée dans la finale sortie. Après analyse, il se retrouve bien dans les résultats de recherche ES. Il est trié, mais dans la sortie finale, lorsque la structure de données ES est convertie en collection, le champ de tri n'est pas ajouté
Analyse du code
Fichier. 1 : /vendor/laravel/scout/src/builder.php Environ 261 lignes - Ligne 305
Regardez attentivement ce fichier. Il existe deux méthodes paginate et paginateRaw La première renvoie la collection laravel et la seconde renvoie la requête native. structure de es. La différence entre les deux codes est la suivante
$results = $this->model->newCollection($engine->map( $this, $rawResults = $engine->paginate($this, $perPage, $page), $this->model )->all());
File 2 :vendor/tamayo/laravel-scout-elastic/src/ElasticsearchEngine.php Ligne 211, méthode map, car nous utilisons ici le moteur ES, si vous utilisez un autre code, cela peut être différent :
public function map(Builder $builder, $results, $model) { //无数据返回空集合 if ($results['hits']['total'] === 0) { return $model->newCollection(); } //获取所有键为_id的ES数据 //$keys = collect($results['hits']['hits'])->pluck('_id')->values()->all(); //转化ES数据并过滤 return $model->getScoutModelsByIds( $builder, $keys )->filter(function ($model) use ($keys) { return in_array($model->getScoutKey(), $keys); }); }
Du point de vue du code, s'il y a des données trouvées dans la recherche, elles seront converties et filtrées pour renvoyer un ensemble qui remplit les conditions. Si elles ne sont pas satisfaites, un ensemble vide sera renvoyé directement
Fichier 3 : /vendor/laravel/scout/src/Searchable.php Environ 171 lignes de la méthode getScoutModelsByIds, code
public function getScoutModelsByIds(Builder $builder, array $ids) { //加入软删除 $query = static::usesSoftDelete() ? $this->withTrashed() : $this->newQuery(); if ($builder->queryCallback) { call_user_func($builder->queryCallback, $query); } // 重点这里,自改代码 // return $query->whereIn( // $this->getScoutKeyName(), $ids // )->orderBy('orderBy','desc')->get(); //官方代码 return $query->whereIn( $this->getScoutKeyName(), $ids )->get(); }
Ce fichier est le point clé La raison principale est que le tri orderBy. Le champ n'a pas été ajouté lors du retour final. Par conséquent, bien que es ait été trié dans la sortie finale, il a été réinitialisé à nouveau. Afin d'empêcher d'autres endroits de pouvoir se mettre à jour après la modification du composant, les données sont renvoyées au niveau du champ. fin. Le traitement de tri a été ajouté, veuillez vous référer au début de l'article pour le plan.
C'est terminé pour le moment, et sera amélioré lorsqu'il sera vide.
Les cinq derniers didacticiels vidéo Laravel
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!