Laravel Scout
簡介
Laravel Scout 提供了一個簡單、基於驅動程式的解決方案,用於為您的 Eloquent 模型新增全文搜尋功能。透過使用模型觀察器,Scout 將自動使您的搜尋索引與您的 Eloquent 記錄保持同步。
目前,Scout 附帶 Algolia、Meilisearch、Typesense 和 MySQL / PostgreSQL (database
) 驅動程式。此外,Scout 還包含一個「集合」驅動程式,該驅動程式專為本地開發使用而設計,並且不需要任何外部依賴或第三方服務。此外,編寫自訂驅動程式非常簡單,您可以自由使用自己的搜尋實作來擴展 Scout。
安裝
首先,透過 Composer 套件管理器安裝 Scout
1composer require laravel/scout
安裝 Scout 後,您應該使用 vendor:publish
Artisan 命令發佈 Scout 設定檔。此命令會將 scout.php
設定檔發佈到您應用程式的 config
目錄中
1php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
最後,將 Laravel\Scout\Searchable
trait 新增到您想要使其可搜尋的模型中。此 trait 將註冊一個模型觀察器,該觀察器將自動使模型與您的搜尋驅動程式保持同步
1<?php 2 3namespace App\Models; 4 5use Illuminate\Database\Eloquent\Model; 6use Laravel\Scout\Searchable; 7 8class Post extends Model 9{10 use Searchable;11}
佇列
雖然並非使用 Scout 的嚴格要求,但在使用該函式庫之前,您應強烈考慮設定 佇列驅動程式。執行佇列工作程序將允許 Scout 將所有同步您的模型資訊到搜尋索引的操作排入佇列,從而為您應用程式的 Web 介面提供更好的回應時間。
設定佇列驅動程式後,將 config/scout.php
設定檔中 queue
選項的值設定為 true
1'queue' => true,
即使 queue
選項設定為 false
,重要的是要記住,某些 Scout 驅動程式(如 Algolia 和 Meilisearch)始終異步索引記錄。這表示,即使索引操作已在您的 Laravel 應用程式中完成,搜尋引擎本身也可能不會立即反映新的和更新的記錄。
若要指定 Scout 任務使用的連線和佇列,您可以將 queue
設定選項定義為陣列
1'queue' => [2 'connection' => 'redis',3 'queue' => 'scout'4],
當然,如果您自訂 Scout 任務使用的連線和佇列,則應執行佇列工作程序以處理該連線和佇列上的任務
1php artisan queue:work redis --queue=scout
驅動程式先決條件
Algolia
使用 Algolia 驅動程式時,您應該在 config/scout.php
設定檔中設定您的 Algolia id
和 secret
憑證。設定憑證後,您還需要透過 Composer 套件管理器安裝 Algolia PHP SDK
1composer require algolia/algoliasearch-client-php
Meilisearch
Meilisearch 是一個極其快速且開源的搜尋引擎。如果您不確定如何在本地電腦上安裝 Meilisearch,可以使用 Laravel Sail,這是 Laravel 官方支援的 Docker 開發環境。
使用 Meilisearch 驅動程式時,您需要透過 Composer 套件管理器安裝 Meilisearch PHP SDK
1composer require meilisearch/meilisearch-php http-interop/http-factory-guzzle
然後,在您應用程式的 .env
檔案中設定 SCOUT_DRIVER
環境變數以及您的 Meilisearch host
和 key
憑證
1SCOUT_DRIVER=meilisearch2MEILISEARCH_HOST=http://127.0.0.1:77003MEILISEARCH_KEY=masterKey
有關 Meilisearch 的更多資訊,請參閱 Meilisearch 文件。
此外,您應確保安裝與您的 Meilisearch 二進位版本相容的 meilisearch/meilisearch-php
版本,方法是查看 Meilisearch 關於二進位相容性的文件。
在升級使用 Meilisearch 的應用程式上的 Scout 時,您應始終 查看 Meilisearch 服務本身是否有任何其他重大變更。
Typesense
Typesense 是一個速度極快的開源搜尋引擎,支援關鍵字搜尋、語意搜尋、地理位置搜尋和向量搜尋。
您可以 自行託管 Typesense 或使用 Typesense Cloud。
若要開始將 Typesense 與 Scout 搭配使用,請透過 Composer 套件管理器安裝 Typesense PHP SDK
1composer require typesense/typesense-php
然後,在您應用程式的 .env 檔案中設定 SCOUT_DRIVER
環境變數以及您的 Typesense 主機和 API 金鑰憑證
1SCOUT_DRIVER=typesense2TYPESENSE_API_KEY=masterKey3TYPESENSE_HOST=localhost
如果您使用 Laravel Sail,您可能需要調整 TYPESENSE_HOST
環境變數以符合 Docker 容器名稱。您也可以選擇性地指定安裝的埠、路徑和協定
1TYPESENSE_PORT=81082TYPESENSE_PATH=3TYPESENSE_PROTOCOL=http
有關 Typesense 集合的其他設定和架構定義,可以在您應用程式的 config/scout.php
設定檔中找到。有關 Typesense 的更多資訊,請參閱 Typesense 文件。
準備要在 Typesense 中儲存的資料
使用 Typesense 時,您的可搜尋模型必須定義一個 toSearchableArray
方法,該方法將您的模型主鍵轉換為字串,並將建立日期轉換為 UNIX 時間戳
1/** 2 * Get the indexable data array for the model. 3 * 4 * @return array<string, mixed> 5 */ 6public function toSearchableArray() 7{ 8 return array_merge($this->toArray(),[ 9 'id' => (string) $this->id,10 'created_at' => $this->created_at->timestamp,11 ]);12}
您還應該在應用程式的 config/scout.php
檔案中定義您的 Typesense 集合架構。集合架構描述了每個可透過 Typesense 搜尋的欄位的資料類型。有關所有可用架構選項的更多資訊,請參閱 Typesense 文件。
如果您需要在定義 Typesense 集合的架構後變更它,您可以執行 scout:flush
和 scout:import
,這將刪除所有現有的索引資料並重新建立架構。或者,您可以使用 Typesense 的 API 修改集合的架構,而無需移除任何索引資料。
如果您的可搜尋模型是可軟刪除的,您應該在模型對應的 Typesense 架構中定義 __soft_deleted
欄位,該架構位於您應用程式的 config/scout.php
設定檔中
1User::class => [ 2 'collection-schema' => [ 3 'fields' => [ 4 // ... 5 [ 6 'name' => '__soft_deleted', 7 'type' => 'int32', 8 'optional' => true, 9 ],10 ],11 ],12],
動態搜尋參數
Typesense 允許您在透過 options
方法執行搜尋操作時,動態修改您的 搜尋參數
1use App\Models\Todo;2 3Todo::search('Groceries')->options([4 'query_by' => 'title, description'5])->get();
設定
設定模型索引
每個 Eloquent 模型都與給定的搜尋「索引」同步,其中包含該模型的所有可搜尋記錄。換句話說,您可以將每個索引視為類似 MySQL 資料表。預設情況下,每個模型都將持久儲存到與模型典型的「資料表」名稱相符的索引中。通常,這是模型名稱的複數形式;但是,您可以透過覆寫模型上的 searchableAs
方法來自訂模型的索引
1<?php 2 3namespace App\Models; 4 5use Illuminate\Database\Eloquent\Model; 6use Laravel\Scout\Searchable; 7 8class Post extends Model 9{10 use Searchable;11 12 /**13 * Get the name of the index associated with the model.14 */15 public function searchableAs(): string16 {17 return 'posts_index';18 }19}
設定可搜尋資料
預設情況下,給定模型的整個 toArray
形式都將持久儲存到其搜尋索引中。如果您想要自訂同步到搜尋索引的資料,您可以覆寫模型上的 toSearchableArray
方法
1<?php 2 3namespace App\Models; 4 5use Illuminate\Database\Eloquent\Model; 6use Laravel\Scout\Searchable; 7 8class Post extends Model 9{10 use Searchable;11 12 /**13 * Get the indexable data array for the model.14 *15 * @return array<string, mixed>16 */17 public function toSearchableArray(): array18 {19 $array = $this->toArray();20 21 // Customize the data array...22 23 return $array;24 }25}
某些搜尋引擎(例如 Meilisearch)只會對正確類型的資料執行篩選操作 (>
、<
等)。因此,當使用這些搜尋引擎並自訂可搜尋資料時,您應確保數值已轉換為其正確的類型
1public function toSearchableArray()2{3 return [4 'id' => (int) $this->id,5 'name' => $this->name,6 'price' => (float) $this->price,7 ];8}
設定索引設定 (Algolia)
有時您可能想要在 Algolia 索引上設定其他設定。雖然您可以透過 Algolia UI 管理這些設定,但直接從應用程式的 config/scout.php
設定檔管理索引設定的所需狀態有時更有效率。
這種方法允許您透過應用程式的自動化部署管道部署這些設定,避免手動設定並確保多個環境之間的一致性。您可以設定可篩選屬性、排名、分面或 任何其他支援的設定。
若要開始使用,請在應用程式的 config/scout.php
設定檔中為每個索引新增設定
1use App\Models\User; 2use App\Models\Flight; 3 4'algolia' => [ 5 'id' => env('ALGOLIA_APP_ID', ''), 6 'secret' => env('ALGOLIA_SECRET', ''), 7 'index-settings' => [ 8 User::class => [ 9 'searchableAttributes' => ['id', 'name', 'email'],10 'attributesForFaceting'=> ['filterOnly(email)'],11 // Other settings fields...12 ],13 Flight::class => [14 'searchableAttributes'=> ['id', 'destination'],15 ],16 ],17],
如果給定索引的底層模型是可軟刪除的,並且包含在 index-settings
陣列中,Scout 將自動包含對該索引上軟刪除模型進行分面支援。如果您的可軟刪除模型索引沒有其他分面屬性要定義,您可以簡單地為該模型的 index-settings
陣列新增一個空項目
1'index-settings' => [2 Flight::class => []3],
設定應用程式的索引設定後,您必須調用 scout:sync-index-settings
Artisan 命令。此命令將通知 Algolia 您目前設定的索引設定。為了方便起見,您可能希望將此命令作為部署過程的一部分
1php artisan scout:sync-index-settings
設定可篩選資料和索引設定 (Meilisearch)
與 Scout 的其他驅動程式不同,Meilisearch 要求您預先定義索引搜尋設定,例如可篩選屬性、可排序屬性和 其他支援的設定欄位。
可篩選屬性是指您計劃在使用 Scout 的 where
方法時進行篩選的任何屬性,而可排序屬性是指您計劃在使用 Scout 的 orderBy
方法時進行排序的任何屬性。若要定義您的索引設定,請調整應用程式 scout
設定檔中 meilisearch
設定項目的 index-settings
部分
1use App\Models\User; 2use App\Models\Flight; 3 4'meilisearch' => [ 5 'host' => env('MEILISEARCH_HOST', 'https://127.0.0.1:7700'), 6 'key' => env('MEILISEARCH_KEY', null), 7 'index-settings' => [ 8 User::class => [ 9 'filterableAttributes'=> ['id', 'name', 'email'],10 'sortableAttributes' => ['created_at'],11 // Other settings fields...12 ],13 Flight::class => [14 'filterableAttributes'=> ['id', 'destination'],15 'sortableAttributes' => ['updated_at'],16 ],17 ],18],
如果給定索引的底層模型是可軟刪除的,並且包含在 index-settings
陣列中,Scout 將自動包含對該索引上軟刪除模型進行篩選的支援。如果您的可軟刪除模型索引沒有其他可定義的篩選或排序屬性,您可以簡單地為該模型在 index-settings
陣列中新增一個空項目
1'index-settings' => [2 Flight::class => []3],
設定應用程式的索引設定後,您必須調用 scout:sync-index-settings
Artisan 命令。此命令將通知 Meilisearch 您目前設定的索引設定。為了方便起見,您可能希望將此命令納入您的部署流程中
1php artisan scout:sync-index-settings
設定模型 ID
預設情況下,Scout 將使用模型的主鍵作為模型的唯一 ID / 鍵,該鍵儲存在搜尋索引中。如果您需要自訂此行為,您可以覆寫模型上的 getScoutKey
和 getScoutKeyName
方法
1<?php 2 3namespace App\Models; 4 5use Illuminate\Database\Eloquent\Model; 6use Laravel\Scout\Searchable; 7 8class User extends Model 9{10 use Searchable;11 12 /**13 * Get the value used to index the model.14 */15 public function getScoutKey(): mixed16 {17 return $this->email;18 }19 20 /**21 * Get the key name used to index the model.22 */23 public function getScoutKeyName(): mixed24 {25 return 'email';26 }27}
為每個模型設定搜尋引擎
搜尋時,Scout 通常會使用在應用程式的 scout
設定檔中指定的預設搜尋引擎。但是,可以通過覆寫模型上的 searchableUsing
方法來更改特定模型的搜尋引擎
1<?php 2 3namespace App\Models; 4 5use Illuminate\Database\Eloquent\Model; 6use Laravel\Scout\Engines\Engine; 7use Laravel\Scout\EngineManager; 8use Laravel\Scout\Searchable; 9 10class User extends Model11{12 use Searchable;13 14 /**15 * Get the engine used to index the model.16 */17 public function searchableUsing(): Engine18 {19 return app(EngineManager::class)->engine('meilisearch');20 }21}
識別使用者
Scout 還允許您在使用 Algolia 時自動識別使用者。將已驗證的使用者與搜尋操作關聯,在 Algolia 儀表板中查看您的搜尋分析時可能會有所幫助。您可以通過在應用程式的 .env
檔案中將 SCOUT_IDENTIFY
環境變數定義為 true
來啟用使用者識別
1SCOUT_IDENTIFY=true
啟用此功能也將把請求的 IP 位址和已驗證使用者的主要識別符傳遞給 Algolia,以便此資料與使用者發出的任何搜尋請求相關聯。
資料庫 / 集合引擎
資料庫引擎
資料庫引擎目前支援 MySQL 和 PostgreSQL。
如果您的應用程式與中小型資料庫互動或工作負載較輕,您可能會發現使用 Scout 的「資料庫」引擎更方便入門。資料庫引擎將在從現有資料庫篩選結果時使用「where like」子句和全文索引,以確定適用於您的查詢的搜尋結果。
若要使用資料庫引擎,您可以簡單地將 SCOUT_DRIVER
環境變數的值設定為 database
,或直接在應用程式的 scout
設定檔中指定 database
驅動程式
1SCOUT_DRIVER=database
一旦您將資料庫引擎指定為首選驅動程式,您必須設定您的可搜尋資料。然後,您可以開始對您的模型執行搜尋查詢。當使用資料庫引擎時,不需要搜尋引擎索引,例如為 Algolia、Meilisearch 或 Typesense 索引建立種子所需的索引。
自訂資料庫搜尋策略
預設情況下,資料庫引擎將針對您已設定為可搜尋的每個模型屬性執行「where like」查詢。但是,在某些情況下,這可能會導致效能不佳。因此,可以設定資料庫引擎的搜尋策略,以便某些指定的資料行使用全文搜尋查詢,或僅使用「where like」約束來搜尋字串的前綴 (example%
),而不是搜尋整個字串 (%example%
)。
若要定義此行為,您可以將 PHP 屬性指派給模型的 toSearchableArray
方法。任何未指派額外搜尋策略行為的資料行將繼續使用預設的「where like」策略
1use Laravel\Scout\Attributes\SearchUsingFullText; 2use Laravel\Scout\Attributes\SearchUsingPrefix; 3 4/** 5 * Get the indexable data array for the model. 6 * 7 * @return array<string, mixed> 8 */ 9#[SearchUsingPrefix(['id', 'email'])]10#[SearchUsingFullText(['bio'])]11public function toSearchableArray(): array12{13 return [14 'id' => $this->id,15 'name' => $this->name,16 'email' => $this->email,17 'bio' => $this->bio,18 ];19}
在指定資料行應使用全文查詢約束之前,請確保已為該資料行指派全文索引。
集合引擎
雖然您可以自由地在本地開發期間使用 Algolia、Meilisearch 或 Typesense 搜尋引擎,但您可能會發現使用「集合」引擎更方便入門。集合引擎將使用「where」子句和集合篩選來篩選現有資料庫的結果,以確定適用於您的查詢的搜尋結果。當使用此引擎時,不需要「索引」您的可搜尋模型,因為它們將僅從您的本地資料庫中檢索。
若要使用集合引擎,您可以簡單地將 SCOUT_DRIVER
環境變數的值設定為 collection
,或直接在應用程式的 scout
設定檔中指定 collection
驅動程式
1SCOUT_DRIVER=collection
一旦您將集合驅動程式指定為首選驅動程式,您可以開始對您的模型執行搜尋查詢。當使用集合引擎時,不需要搜尋引擎索引,例如為 Algolia、Meilisearch 或 Typesense 索引建立種子所需的索引。
與資料庫引擎的不同之處
乍看之下,「資料庫」和「集合」引擎非常相似。它們都直接與您的資料庫互動以檢索搜尋結果。但是,集合引擎不使用全文索引或 LIKE
子句來尋找匹配的記錄。相反,它會拉取所有可能的記錄,並使用 Laravel 的 Str::is
輔助函數來確定搜尋字串是否存在於模型屬性值中。
集合引擎是最具可移植性的搜尋引擎,因為它適用於 Laravel 支援的所有關聯式資料庫(包括 SQLite 和 SQL Server);但是,它的效率不如 Scout 的資料庫引擎。
索引
批次匯入
如果您要將 Scout 安裝到現有專案中,您可能已經有需要匯入到索引中的資料庫記錄。Scout 提供了 scout:import
Artisan 命令,您可以使用它將所有現有記錄匯入到您的搜尋索引中
1php artisan scout:import "App\Models\Post"
flush
命令可用於從您的搜尋索引中移除模型的所有記錄
1php artisan scout:flush "App\Models\Post"
修改匯入查詢
如果您想修改用於檢索所有模型以進行批次匯入的查詢,您可以在模型上定義 makeAllSearchableUsing
方法。這是新增任何在匯入模型之前可能需要的預先載入關係的好地方
1use Illuminate\Database\Eloquent\Builder;2 3/**4 * Modify the query used to retrieve models when making all of the models searchable.5 */6protected function makeAllSearchableUsing(Builder $query): Builder7{8 return $query->with('author');9}
當使用佇列來批次匯入模型時,makeAllSearchableUsing
方法可能不適用。當模型集合由任務處理時,關係不會還原。
新增記錄
一旦您將 Laravel\Scout\Searchable
特性新增到模型中,您只需 save
或 create
模型實例,它就會自動新增到您的搜尋索引中。如果您已將 Scout 設定為使用佇列,則此操作將由您的佇列工作程序在背景中執行
1use App\Models\Order;2 3$order = new Order;4 5// ...6 7$order->save();
通過查詢新增記錄
如果您想通過 Eloquent 查詢將模型集合新增到您的搜尋索引,您可以將 searchable
方法鏈接到 Eloquent 查詢上。searchable
方法將分塊處理查詢結果,並將記錄新增到您的搜尋索引中。同樣,如果您已將 Scout 設定為使用佇列,則所有區塊都將由您的佇列工作程序在背景中匯入
1use App\Models\Order;2 3Order::where('price', '>', 100)->searchable();
您也可以在 Eloquent 關係實例上調用 searchable
方法
1$user->orders()->searchable();
或者,如果您已經在記憶體中擁有 Eloquent 模型集合,您可以在集合實例上調用 searchable
方法,將模型實例新增到其對應的索引中
1$orders->searchable();
searchable
方法可以被視為「upsert」操作。換句話說,如果模型記錄已存在於您的索引中,它將被更新。如果它不存在於搜尋索引中,它將被新增到索引中。
更新記錄
若要更新可搜尋模型,您只需更新模型實例的屬性並 save
模型到您的資料庫。Scout 將自動將變更持久化到您的搜尋索引
1use App\Models\Order;2 3$order = Order::find(1);4 5// Update the order...6 7$order->save();
您也可以在 Eloquent 查詢實例上調用 searchable
方法來更新模型集合。如果模型不存在於您的搜尋索引中,它們將被建立
1Order::where('price', '>', 100)->searchable();
如果您想更新關係中所有模型的搜尋索引記錄,您可以在關係實例上調用 searchable
1$user->orders()->searchable();
或者,如果您已經在記憶體中擁有 Eloquent 模型集合,您可以在集合實例上調用 searchable
方法,以更新模型實例在其對應索引中的記錄
1$orders->searchable();
匯入前修改記錄
有時您可能需要在模型集合可搜尋之前準備它們。例如,您可能想要預先載入關係,以便可以有效地將關係資料新增到您的搜尋索引中。若要完成此操作,請在對應的模型上定義 makeSearchableUsing
方法
1use Illuminate\Database\Eloquent\Collection;2 3/**4 * Modify the collection of models being made searchable.5 */6public function makeSearchableUsing(Collection $models): Collection7{8 return $models->load('author');9}
移除記錄
若要從索引中移除記錄,您可以簡單地從資料庫中 delete
模型。即使您使用軟刪除模型,也可以這樣做
1use App\Models\Order;2 3$order = Order::find(1);4 5$order->delete();
如果您不想在刪除記錄之前檢索模型,您可以在 Eloquent 查詢實例上使用 unsearchable
方法
1Order::where('price', '>', 100)->unsearchable();
如果您想移除關係中所有模型的搜尋索引記錄,您可以在關係實例上調用 unsearchable
1$user->orders()->unsearchable();
或者,如果您已經在記憶體中擁有 Eloquent 模型集合,您可以在集合實例上調用 unsearchable
方法,從其對應的索引中移除模型實例
1$orders->unsearchable();
若要從其對應的索引中移除所有模型記錄,您可以調用 removeAllFromSearch
方法
1Order::removeAllFromSearch();
暫停索引
有時您可能需要在模型上執行一批 Eloquent 操作,而無需將模型資料同步到您的搜尋索引。您可以使用 withoutSyncingToSearch
方法執行此操作。此方法接受一個閉包,該閉包將立即執行。在閉包內發生的任何模型操作都不會同步到模型的索引
1use App\Models\Order;2 3Order::withoutSyncingToSearch(function () {4 // Perform model actions...5});
有條件地可搜尋的模型實例
有時您可能需要僅在特定條件下使模型可搜尋。例如,假設您有一個 App\Models\Post
模型,它可能處於兩種狀態之一:「草稿」和「已發布」。您可能只想允許「已發布」的文章可搜尋。若要完成此操作,您可以在模型上定義 shouldBeSearchable
方法
1/**2 * Determine if the model should be searchable.3 */4public function shouldBeSearchable(): bool5{6 return $this->isPublished();7}
shouldBeSearchable
方法僅在通過 save
和 create
方法、查詢或關係操作模型時應用。直接使用 searchable
方法使模型或集合可搜尋將覆寫 shouldBeSearchable
方法的結果。
當使用 Scout 的「資料庫」引擎時,shouldBeSearchable
方法不適用,因為所有可搜尋資料始終儲存在資料庫中。若要在使用資料庫引擎時實現類似的行為,您應該改用where 子句。
搜尋
您可以使用 search
方法開始搜尋模型。search 方法接受一個字串,該字串將用於搜尋您的模型。然後,您應該將 get
方法鏈接到搜尋查詢上,以檢索與給定搜尋查詢匹配的 Eloquent 模型
1use App\Models\Order;2 3$orders = Order::search('Star Trek')->get();
由於 Scout 搜尋返回 Eloquent 模型集合,您甚至可以直接從路由或控制器返回結果,它們將自動轉換為 JSON
1use App\Models\Order;2use Illuminate\Http\Request;3 4Route::get('/search', function (Request $request) {5 return Order::search($request->search)->get();6});
如果您想在搜尋結果轉換為 Eloquent 模型之前取得原始搜尋結果,您可以使用 raw
方法
1$orders = Order::search('Star Trek')->raw();
自訂索引
搜尋查詢通常會在模型的searchableAs
方法指定的索引上執行。但是,您可以使用 within
方法來指定應搜尋的自訂索引
1$orders = Order::search('Star Trek')2 ->within('tv_shows_popularity_desc')3 ->get();
Where 條件子句
Scout 允許您向搜尋查詢新增簡單的「where」子句。目前,這些子句僅支援基本的數值相等性檢查,主要用於按所有者 ID 劃分搜尋查詢的範圍
1use App\Models\Order;2 3$orders = Order::search('Star Trek')->where('user_id', 1)->get();
此外,whereIn
方法可用於驗證給定資料行的值是否包含在給定陣列中
1$orders = Order::search('Star Trek')->whereIn(2 'status', ['open', 'paid']3)->get();
whereNotIn
方法驗證給定資料行的值是否未包含在給定陣列中
1$orders = Order::search('Star Trek')->whereNotIn(2 'status', ['closed']3)->get();
由於搜尋索引不是關聯式資料庫,因此目前不支援更進階的「where」子句。
如果您的應用程式正在使用 Meilisearch,您必須在利用 Scout 的「where」子句之前,設定應用程式的可篩選屬性。
分頁
除了檢索模型集合外,您可以使用 paginate
方法對搜尋結果進行分頁。此方法將返回 Illuminate\Pagination\LengthAwarePaginator
實例,就像您已分頁傳統 Eloquent 查詢一樣
1use App\Models\Order;2 3$orders = Order::search('Star Trek')->paginate();
您可以通過將數量作為第一個參數傳遞給 paginate
方法來指定每頁檢索多少模型
1$orders = Order::search('Star Trek')->paginate(15);
檢索結果後,您可以像分頁傳統 Eloquent 查詢一樣,使用 Blade 顯示結果並呈現頁面連結
1<div class="container">2 @foreach ($orders as $order)3 {{ $order->price }}4 @endforeach5</div>6 7{{ $orders->links() }}
當然,如果您想以 JSON 格式檢索分頁結果,您可以直接從路由或控制器返回分頁器實例
1use App\Models\Order;2use Illuminate\Http\Request;3 4Route::get('/orders', function (Request $request) {5 return Order::search($request->input('query'))->paginate(15);6});
由於搜尋引擎不知道您的 Eloquent 模型的全域範圍定義,因此您不應在使用 Scout 分頁的應用程式中使用全域範圍。或者,您應該在使用 Scout 搜尋時重新建立全域範圍的約束。
軟刪除
如果您的索引模型是軟刪除,並且您需要搜尋您的軟刪除模型,請將 config/scout.php
設定檔的 soft_delete
選項設定為 true
1'soft_delete' => true,
當此設定選項為 true
時,Scout 將不會從搜尋索引中移除軟刪除模型。相反,它將在索引記錄上設定一個隱藏的 __soft_deleted
屬性。然後,您可以使用 withTrashed
或 onlyTrashed
方法在搜尋時檢索軟刪除記錄
1use App\Models\Order;2 3// Include trashed records when retrieving results...4$orders = Order::search('Star Trek')->withTrashed()->get();5 6// Only include trashed records when retrieving results...7$orders = Order::search('Star Trek')->onlyTrashed()->get();
當使用 forceDelete
永久刪除軟刪除模型時,Scout 將自動從搜尋索引中移除它。
自訂引擎搜尋
如果您需要對引擎的搜尋行為執行進階自訂,您可以將閉包作為第二個參數傳遞給 search
方法。例如,您可以使用此回呼在搜尋查詢傳遞給 Algolia 之前,將地理位置資料新增到您的搜尋選項
1use Algolia\AlgoliaSearch\SearchIndex; 2use App\Models\Order; 3 4Order::search( 5 'Star Trek', 6 function (SearchIndex $algolia, string $query, array $options) { 7 $options['body']['query']['bool']['filter']['geo_distance'] = [ 8 'distance' => '1000km', 9 'location' => ['lat' => 36, 'lon' => 111],10 ];11 12 return $algolia->search($query, $options);13 }14)->get();
自訂 Eloquent 結果查詢
在 Scout 從您的應用程式的搜尋引擎中檢索到符合條件的 Eloquent 模型列表後,Eloquent 會被用來透過模型的主鍵檢索所有符合條件的模型。您可以透過調用 query
方法來自訂此查詢。query
方法接受一個閉包(closure),該閉包將接收 Eloquent query builder 實例作為參數。
1use App\Models\Order;2use Illuminate\Database\Eloquent\Builder;3 4$orders = Order::search('Star Trek')5 ->query(fn (Builder $query) => $query->with('invoices'))6 ->get();
由於此回呼函數是在相關模型已從您的應用程式的搜尋引擎中檢索之後才調用,因此 query
方法不應該被用於「過濾」結果。相反地,您應該使用Scout where 條件子句。
自訂引擎
撰寫引擎
如果內建的 Scout 搜尋引擎不符合您的需求,您可以撰寫自己的自訂引擎並將其註冊到 Scout。您的引擎應該繼承 Laravel\Scout\Engines\Engine
抽象類別。此抽象類別包含您的自訂引擎必須實作的八個方法。
1use Laravel\Scout\Builder; 2 3abstract public function update($models); 4abstract public function delete($models); 5abstract public function search(Builder $builder); 6abstract public function paginate(Builder $builder, $perPage, $page); 7abstract public function mapIds($results); 8abstract public function map(Builder $builder, $results, $model); 9abstract public function getTotalCount($results);10abstract public function flush($model);
您可能會發現檢閱 Laravel\Scout\Engines\AlgoliaEngine
類別上這些方法的實作方式很有幫助。這個類別將為您提供一個良好的起點,以學習如何在您自己的引擎中實作這些方法中的每一個。
註冊引擎
一旦您撰寫了自訂引擎,您可以使用 Scout 引擎管理器的 extend
方法將其註冊到 Scout。Scout 的引擎管理器可以從 Laravel 服務容器中解析。您應該從 App\Providers\AppServiceProvider
類別或您的應用程式使用的任何其他服務提供者的 boot
方法中呼叫 extend
方法。
1use App\ScoutExtensions\MySqlSearchEngine; 2use Laravel\Scout\EngineManager; 3 4/** 5 * Bootstrap any application services. 6 */ 7public function boot(): void 8{ 9 resolve(EngineManager::class)->extend('mysql', function () {10 return new MySqlSearchEngine;11 });12}
一旦您的引擎被註冊,您可以在您的應用程式的 config/scout.php
設定檔中將其指定為您的預設 Scout driver
。
1'driver' => 'mysql',