如何解決laravel排序失效問題
laravel排序失效的解決方法:1、透過「$query->whereIn(...)」查詢資料;2、透過filter過濾資料;3、設定排序好的資料為「$data = $scoutModelsLists;」。
本文操作環境:Windows7系統、Laravel5.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 ,前一個返回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影片教學(推薦)
以上是如何解決laravel排序失效問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Laravel郵件發送失敗時的退信代碼獲取方法在使用Laravel開發應用時,經常會遇到需要發送驗證碼的情況。而在實�...

在dcatadmin(laravel-admin)中如何實現自定義點擊添加數據的表格功能在使用dcat...

Laravel框架中Redis連接的共享與select方法的影響在使用Laravel框架和Redis時,開發者可能會遇到一個問題:通過配置...

在Laravel多租戶擴展包stancl/tenancy中自定義租戶數據庫連接使用Laravel多租戶擴展包stancl/tenancy構建多租戶應用時,...

LaravelEloquent模型檢索:輕鬆獲取數據庫數據EloquentORM提供了簡潔易懂的方式來操作數據庫。本文將詳細介紹各種Eloquent模型檢索技巧,助您高效地從數據庫中獲取數據。 1.獲取所有記錄使用all()方法可以獲取數據庫表中的所有記錄:useApp\Models\Post;$posts=Post::all();這將返回一個集合(Collection)。您可以使用foreach循環或其他集合方法訪問數據:foreach($postsas$post){echo$post->

在Laravel6項目中如何檢查Redis連接的有效性是一個常見的問題,特別是在項目依賴於Redis進行業務處理時。以下是...

Laravel數據庫遷移過程中出現類重複定義問題在使用Laravel框架進行數據庫遷移時,開發者可能會遇到“類已使用�...

Laravel 是一款 PHP 框架,用於輕鬆構建 Web 應用程序。它提供一系列強大的功能,包括:安裝: 使用 Composer 全局安裝 Laravel CLI,並在項目目錄中創建應用程序。路由: 在 routes/web.php 中定義 URL 和處理函數之間的關係。視圖: 在 resources/views 中創建視圖以呈現應用程序的界面。數據庫集成: 提供與 MySQL 等數據庫的開箱即用集成,並使用遷移來創建和修改表。模型和控制器: 模型表示數據庫實體,控制器處理 HTTP 請求。
