您好,登錄后才能下訂單哦!
這篇文章主要介紹“怎么解決laravel排序失效問題”,在日常操作中,相信很多人在怎么解決laravel排序失效問題問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么解決laravel排序失效問題”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
laravel排序失效的解決辦法:1、通過“$query->whereIn(...)”查詢數據;2、通過filter過濾數據;3、設置排序好的數據為“$data = $scoutModelsLists;”。
本文操作環境:Windows7系統、Laravel5.8版、Dell G3電腦。
如何解決laravel排序失效問題?
Laravel 5.8+scout7.0 使用 orderBy 排序失效解決方案
最近在使用 elasticSearch7.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 ,前一個返回 laravel 集合,后一個返回 es 的原生查詢結構,
這兩者代碼的不同點在于這塊
$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排序失效問題”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。