使用 Eloquent 輕鬆搜尋多個模型

laradocs發表於2021-10-04

前言

有些時候,我們需要實現一個跨多個模型搜尋並返回統一的結果。我以為需要一個第三方包來實現這一點。事實證明,使用 Eloquent 就可以做到。

快速開始

模型

假如我們需要搜尋兩個不同的模型,即 UserCompany 模型。

School 的結構如下所示:

Company 的結構如下所示:

查詢

例如我們要搜尋任何與 nameharvard 匹配的記錄。

要單獨執行,我們需要這樣的查詢:

School::where ( 'name', 'LIKE', '%harvard%' )->get();
Company::where ( 'name', 'LIKE', '%harvard%' )->get();

為了將查詢合併為 1 個結果集,我們需要做一些事情:

  1. 使用 UNION 將查詢合併為 1 條。
  2. 為了使用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();

為了使兩個表之間的列匹配,我們必須將 chancellorceo 轉換為 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();

我們會得到一個看起來像這樣的記錄列表:

總結

這裡有幾點需要注意:

  1. 我們用 get() 從單個查詢中取出,僅將其應用於最終的 UNION 查詢。
  2. 我們在查詢中新增了一個 type,以便我們知道記錄來自哪裡。
  3. 使用 UNION 查詢的同時你也可以使用分頁。
  4. 合併表/模型的數量沒有限制。
本作品採用《CC 協議》,轉載必須註明作者和本文連結
站在巨人的肩上

相關文章