前言
有些時候,我們需要實現一個跨多個模型搜尋並返回統一的結果。我以為需要一個第三方包來實現這一點。事實證明,使用 Eloquent 就可以做到。
快速開始
模型
假如我們需要搜尋兩個不同的模型,即 User
和 Company
模型。
School
的結構如下所示:
Company
的結構如下所示:
查詢
例如我們要搜尋任何與 name
為 harvard
匹配的記錄。
要單獨執行,我們需要這樣的查詢:
School::where ( 'name', 'LIKE', '%harvard%' )->get();
Company::where ( 'name', 'LIKE', '%harvard%' )->get();
為了將查詢合併為 1 個結果集,我們需要做一些事情:
- 使用 UNION 將查詢合併為 1 條。
- 為了使用UNION操作,需要確保從所有查詢返回的欄位是相同的,否則就會出現錯誤。
現在我們可以得到新的查詢:
School::select ( 'id', 'name', \DB::raw ( 'chancellor AS leader' ) )
->where ( 'name', 'LIKE', '%harvard%' )
->get();
Company::select ( 'id', 'name', \DB::raw ( 'ceo AS leader' ) )
->where ( 'name', 'LIKE', '%harvard%' )
->get();
為了使兩個表之間的列匹配,我們必須將 chancellor
和 ceo
轉換為 leader
。
我們對兩個查詢的返回結果如下所示:
合併
最後,將 UNION
應用到我們的查詢中:
$query1 = School::select (
'id',
'name',
\DB::raw ( 'chancellor AS leader' ),
\DB::raw ( '"school" AS type' )
)->where ( 'name', 'LIKE', '%harvard%' );
$query2 = Company::select (
'id',
'name',
\DB::raw ( 'ceo AS leader' ),
\DB::raw ( '"company" AS type' )
)->where ( 'name', 'LIKE', '%harvard%' );
$query2->union ( $query1 )->get();
我們會得到一個看起來像這樣的記錄列表:
總結
這裡有幾點需要注意:
- 我們用
get()
從單個查詢中取出,僅將其應用於最終的 UNION 查詢。 - 我們在查詢中新增了一個
type
,以便我們知道記錄來自哪裡。 - 使用 UNION 查詢的同時你也可以使用分頁。
- 合併表/模型的數量沒有限制。
本作品採用《CC 協議》,轉載必須註明作者和本文連結