laravel ソート失敗の解決策: 1. "$query->whereIn(...)" を通じてデータをクエリする; 2. フィルターを通じてデータをフィルターする; 3. ソートされたデータを "$data = $" に設定するスカウトモデルリスト;"。
この記事の動作環境: Windows 7 システム、Laravel バージョン 5.8、Dell G3 コンピューター。
laravel のソート失敗問題を解決するにはどうすればよいですか?
Laravel 5.8 scout7.0 orderByを使ったソート失敗解決方法
最近、elasticSearch6.2.4を使って検索したところ、ソートフィールドが無効であることが判明したので、ここに記録
まずソリューションを見てみましょう。これ以上苦労することなく、コードに直接行きましょう
$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;
問題分析
元のコード使用したクエリ文は
$list = Article::search($words)->orderBy('created_at','desc')->paginate(10)->toArray();
上記のクエリ文はソートフィールドを設定していますが、最終出力時にはソートされていません 解析後のESの検索結果では確かにソートされていますが、最終出力時にはソートされていません、ES データ構造はセットに変換され、ソート フィールドは追加されません
コード分析
ファイル 1: /vendor/laravel/scout/src/builder .php 約261行~305行
このファイルをよく見ると、paginateとpaginateRawの2つのメソッドがあり、前者はlaravelのコレクションを返し、後者はesのネイティブクエリ構造を返します。
2 つのコードの違いはこのブロックにあります
$results = $this->model->newCollection($engine->map( $this, $rawResults = $engine->paginate($this, $perPage, $page), $this->model )->all());
ファイル 2:vendor/tamayo/laravel-scout-elastic/src/ElasticsearchEngine.php 行 211、map メソッド。 ES エンジンを使用しています。他のエンジンを使用している場合は、コードが異なる可能性があります。
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); }); }
コードの観点から見ると、es がデータを検索すると、変換およびフィルタリングされて、次のセットが返されます。条件を満たしている場合は、空の
ファイル 3: /vendor/laravel/scout/ src/Searchable.php は約 171 行です getScoutModelsByIds メソッド、コード
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(); }
このファイルが焦点ですが、主に最終返却時にorderByソートフィールドが追加されないため、最終出力ではesがソートされていますが、ここでもまたリセットされています。コンポーネントを変更した後に更新し、最終的にデータが返されたときにソートが追加されます。計画については記事の冒頭を参照してください。
とりあえず終わったので空いたら改良します。
以上がLaravelのソート失敗問題を解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。