跳至內容

Laravel Scout

簡介

Laravel Scout 提供一個簡單、基於驅動程式的解決方案,可為您的 Eloquent 模型新增全文搜尋。透過使用模型觀察者,Scout 將自動讓您的搜尋索引與您的 Eloquent 記錄保持同步。

目前,Scout 隨附 AlgoliaMeilisearchTypesense 和 MySQL / PostgreSQL(database)驅動程式。此外,Scout 還包含一個「集合」驅動程式,該驅動程式專為本機開發使用而設計,且不需要任何外部相依性或第三方服務。此外,編寫自訂驅動程式很簡單,您可以自由使用您自己的搜尋實作來擴充 Scout。

安裝

首先,透過 Composer 套件管理器安裝 Scout

composer require laravel/scout

安裝 Scout 後,您應該使用 vendor:publish Artisan 命令發佈 Scout 設定檔。此命令會將 scout.php 設定檔發佈到您應用程式的 config 目錄

php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"

最後,將 Laravel\Scout\Searchable 特性新增至您想要設為可搜尋的模型。此特性將註冊一個模型觀察者,該觀察者會自動讓模型與您的搜尋驅動程式保持同步

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;
 
class Post extends Model
{
use Searchable;
}

佇列

雖然並非使用 Scout 的絕對必要條件,但在使用程式庫之前,您應該強烈考慮設定佇列驅動程式。執行佇列工作者將允許 Scout 將所有同步模型資訊至搜尋索引的操作放入佇列,從而為您應用程式的網頁介面提供更佳的響應時間。

設定佇列驅動程式後,將 config/scout.php 設定檔中的 queue 選項值設定為 true

'queue' => true,

即使 queue 選項設定為 false,也務必記住某些 Scout 驅動程式(例如 Algolia 和 Meilisearch)始終會以非同步方式索引記錄。也就是說,即使索引操作已在您的 Laravel 應用程式內完成,搜尋引擎本身可能不會立即反映新的和更新的記錄。

若要指定您的 Scout 工作利用的連線和佇列,您可以將 queue 設定選項定義為陣列

'queue' => [
'connection' => 'redis',
'queue' => 'scout'
],

當然,如果您自訂 Scout 工作利用的連線和佇列,您應該執行佇列工作者以處理該連線和佇列上的工作

php artisan queue:work redis --queue=scout

驅動程式先決條件

Algolia

使用 Algolia 驅動程式時,您應該在 config/scout.php 設定檔中設定您的 Algolia idsecret 憑證。設定憑證後,您還需要透過 Composer 套件管理器安裝 Algolia PHP SDK

composer require algolia/algoliasearch-client-php

Meilisearch

Meilisearch 是一個快速且開源的搜尋引擎。如果您不確定如何在您的本機電腦上安裝 Meilisearch,您可以使用 Laravel Sail,這是 Laravel 官方支援的 Docker 開發環境。

使用 Meilisearch 驅動程式時,您需要透過 Composer 套件管理器安裝 Meilisearch PHP SDK

composer require meilisearch/meilisearch-php http-interop/http-factory-guzzle

然後,在您應用程式的 .env 檔案中設定 SCOUT_DRIVER 環境變數以及您的 Meilisearch hostkey 憑證

SCOUT_DRIVER=meilisearch
MEILISEARCH_HOST=http://127.0.0.1:7700
MEILISEARCH_KEY=masterKey

如需有關 Meilisearch 的詳細資訊,請參閱 Meilisearch 文件

此外,您應該透過檢閱 Meilisearch 關於二進位相容性的文件,確保您安裝的 meilisearch/meilisearch-php 版本與您的 Meilisearch 二進位版本相容。

exclamation

在使用 Meilisearch 的應用程式上升級 Scout 時,您應該始終檢閱 Meilisearch 服務本身的任何其他重大變更

Typesense

Typesense 是一個速度極快的開源搜尋引擎,支援關鍵字搜尋、語意搜尋、地理搜尋和向量搜尋。

您可以自行託管 Typesense 或使用 Typesense Cloud

若要開始使用 Typesense 和 Scout,請透過 Composer 套件管理器安裝 Typesense PHP SDK

composer require typesense/typesense-php

然後,在您應用程式的 .env 檔案中設定 SCOUT_DRIVER 環境變數以及您的 Typesense 主機和 API 金鑰憑證

SCOUT_DRIVER=typesense
TYPESENSE_API_KEY=masterKey
TYPESENSE_HOST=localhost

如果您使用 Laravel Sail,您可能需要調整 TYPESENSE_HOST 環境變數以符合 Docker 容器名稱。您也可以選擇性地指定您安裝的埠、路徑和協定

TYPESENSE_PORT=8108
TYPESENSE_PATH=
TYPESENSE_PROTOCOL=http

您的 Typesense 集合的其他設定和結構定義可以在您應用程式的 config/scout.php 設定檔中找到。如需有關 Typesense 的詳細資訊,請參閱 Typesense 文件

準備要儲存在 Typesense 中的資料

使用 Typesense 時,您的可搜尋模型必須定義一個 toSearchableArray 方法,該方法會將您模型的主鍵轉換為字串,並將建立日期轉換為 UNIX 時間戳記

/**
* Get the indexable data array for the model.
*
* @return array<string, mixed>
*/
public function toSearchableArray()
{
return array_merge($this->toArray(),[
'id' => (string) $this->id,
'created_at' => $this->created_at->timestamp,
]);
}

您也應該在您應用程式的 config/scout.php 檔案中定義您的 Typesense 集合結構定義。集合結構定義會描述每個可透過 Typesense 搜尋的欄位的資料類型。如需所有可用結構選項的詳細資訊,請參閱 Typesense 文件

如果您需要在定義 Typesense 集合的結構定義之後進行變更,您可以執行 scout:flushscout:import,這會刪除所有現有索引資料並重新建立結構定義。或者,您可以使用 Typesense 的 API 來修改集合的結構定義,而不會移除任何索引資料。

如果您的可搜尋模型是可軟刪除的,您應該在您應用程式的 config/scout.php 設定檔中的模型對應 Typesense 結構定義中定義 __soft_deleted 欄位

User::class => [
'collection-schema' => [
'fields' => [
// ...
[
'name' => '__soft_deleted',
'type' => 'int32',
'optional' => true,
],
],
],
],

動態搜尋參數

Typesense 允許您在透過 options 方法執行搜尋操作時動態修改您的搜尋參數

use App\Models\Todo;
 
Todo::search('Groceries')->options([
'query_by' => 'title, description'
])->get();

設定

設定模型索引

每個 Eloquent 模型都與一個指定的搜尋「索引」同步,其中包含該模型的所有可搜尋記錄。換句話說,您可以將每個索引視為 MySQL 資料表。根據預設,每個模型都會保存到符合模型一般「資料表」名稱的索引中。通常,這是模型名稱的複數形式;但是,您可以自由透過覆寫模型上的 searchableAs 方法來自訂模型的索引

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;
 
class Post extends Model
{
use Searchable;
 
/**
* Get the name of the index associated with the model.
*/
public function searchableAs(): string
{
return 'posts_index';
}
}

設定可搜尋的資料

預設情況下,指定模型的所有 toArray 格式數據都會被儲存到其搜尋索引中。如果您想自訂同步到搜尋索引的數據,可以覆寫模型上的 toSearchableArray 方法。

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;
 
class Post extends Model
{
use Searchable;
 
/**
* Get the indexable data array for the model.
*
* @return array<string, mixed>
*/
public function toSearchableArray(): array
{
$array = $this->toArray();
 
// Customize the data array...
 
return $array;
}
}

某些搜尋引擎(如 Meilisearch)只會對正確類型的數據執行篩選操作(>< 等)。因此,當使用這些搜尋引擎並自訂您的可搜尋數據時,您應確保數值被轉換為它們正確的類型。

public function toSearchableArray()
{
return [
'id' => (int) $this->id,
'name' => $this->name,
'price' => (float) $this->price,
];
}

設定可篩選數據和索引設定 (Meilisearch)

與 Scout 的其他驅動程式不同,Meilisearch 需要您預先定義索引搜尋設定,例如可篩選的屬性、可排序的屬性,以及其他支援的設定欄位

可篩選的屬性是您在調用 Scout 的 where 方法時計劃用於篩選的任何屬性,而可排序的屬性是您在調用 Scout 的 orderBy 方法時計劃用於排序的任何屬性。要定義您的索引設定,請調整應用程式 scout 設定檔中 meilisearch 設定項的 index-settings 部分。

use App\Models\User;
use App\Models\Flight;
 
'meilisearch' => [
'host' => env('MEILISEARCH_HOST', 'https://127.0.0.1:7700'),
'key' => env('MEILISEARCH_KEY', null),
'index-settings' => [
User::class => [
'filterableAttributes'=> ['id', 'name', 'email'],
'sortableAttributes' => ['created_at'],
// Other settings fields...
],
Flight::class => [
'filterableAttributes'=> ['id', 'destination'],
'sortableAttributes' => ['updated_at'],
],
],
],

如果給定索引底層的模型是軟刪除的,並且包含在 index-settings 陣列中,Scout 將自動包含對該索引上軟刪除模型進行篩選的支援。如果您的軟刪除模型索引沒有其他可篩選或可排序的屬性要定義,您可以簡單地為該模型在 index-settings 陣列中新增一個空項目。

'index-settings' => [
Flight::class => []
],

在設定好應用程式的索引設定後,您必須調用 scout:sync-index-settings Artisan 命令。此命令會通知 Meilisearch 您當前設定的索引設定。為方便起見,您可以將此命令作為部署過程的一部分。

php artisan scout:sync-index-settings

設定模型 ID

預設情況下,Scout 會使用模型的主鍵作為儲存在搜尋索引中的模型的唯一 ID/鍵。如果您需要自訂此行為,可以覆寫模型上的 getScoutKeygetScoutKeyName 方法。

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;
 
class User extends Model
{
use Searchable;
 
/**
* Get the value used to index the model.
*/
public function getScoutKey(): mixed
{
return $this->email;
}
 
/**
* Get the key name used to index the model.
*/
public function getScoutKeyName(): mixed
{
return 'email';
}
}

為每個模型設定搜尋引擎

在搜尋時,Scout 通常會使用您應用程式 scout 設定檔中指定的預設搜尋引擎。但是,特定模型的搜尋引擎可以通過覆寫模型上的 searchableUsing 方法來更改。

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Engines\Engine;
use Laravel\Scout\EngineManager;
use Laravel\Scout\Searchable;
 
class User extends Model
{
use Searchable;
 
/**
* Get the engine used to index the model.
*/
public function searchableUsing(): Engine
{
return app(EngineManager::class)->engine('meilisearch');
}
}

識別使用者

當使用 Algolia 時,Scout 還允許您自動識別使用者。在 Algolia 的儀表板中查看您的搜尋分析時,將已驗證的使用者與搜尋操作關聯起來可能會很有幫助。您可以在應用程式的 .env 檔案中將 SCOUT_IDENTIFY 環境變數定義為 true 來啟用使用者識別。

SCOUT_IDENTIFY=true

啟用此功能也會將請求的 IP 位址和您已驗證使用者的主要識別符傳遞給 Algolia,以便此數據與使用者發出的任何搜尋請求相關聯。

資料庫 / 集合引擎

資料庫引擎

exclamation

資料庫引擎目前支援 MySQL 和 PostgreSQL。

如果您的應用程式與小型到中型的資料庫互動或工作負載較輕,您可能會發現使用 Scout 的「資料庫」引擎更方便。當從您現有的資料庫篩選結果以確定適用於您查詢的搜尋結果時,資料庫引擎將使用「where like」子句和全文索引。

要使用資料庫引擎,您可以簡單地將 SCOUT_DRIVER 環境變數的值設定為 database,或直接在應用程式的 scout 設定檔中指定 database 驅動程式。

SCOUT_DRIVER=database

一旦您將資料庫引擎指定為首選驅動程式,您必須設定您的可搜尋數據。然後,您可以開始針對您的模型執行搜尋查詢。當使用資料庫引擎時,不需要搜尋引擎索引,例如將資料匯入 Algolia、Meilisearch 或 Typesense 索引所需的索引。

自訂資料庫搜尋策略

預設情況下,資料庫引擎將針對您設定為可搜尋的每個模型屬性執行「where like」查詢。但是,在某些情況下,這可能會導致效能不佳。因此,可以設定資料庫引擎的搜尋策略,以便某些指定的列使用全文搜尋查詢,或僅使用「where like」約束來搜尋字串的前綴 (example%),而不是在整個字串中搜尋 (%example%)。

要定義此行為,您可以在模型的 toSearchableArray 方法中指定 PHP 屬性。任何未分配額外搜尋策略行為的列將繼續使用預設的「where like」策略。

use Laravel\Scout\Attributes\SearchUsingFullText;
use Laravel\Scout\Attributes\SearchUsingPrefix;
 
/**
* Get the indexable data array for the model.
*
* @return array<string, mixed>
*/
#[SearchUsingPrefix(['id', 'email'])]
#[SearchUsingFullText(['bio'])]
public function toSearchableArray(): array
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'bio' => $this->bio,
];
}
exclamation

在指定某個列應使用全文查詢約束之前,請確保該列已被分配了全文索引

集合引擎

雖然您可以在本機開發期間自由使用 Algolia、Meilisearch 或 Typesense 搜尋引擎,但您可能會發現使用「集合」引擎更方便。「集合」引擎將使用「where」子句和對現有資料庫結果的集合篩選,以確定適用於您查詢的搜尋結果。當使用此引擎時,不需要「索引」您的可搜尋模型,因為它們將直接從您的本機資料庫中檢索。

要使用集合引擎,您可以簡單地將 SCOUT_DRIVER 環境變數的值設定為 collection,或直接在應用程式的 scout 設定檔中指定 collection 驅動程式。

SCOUT_DRIVER=collection

一旦您將集合驅動程式指定為首選驅動程式,您就可以開始針對您的模型執行搜尋查詢。當使用集合引擎時,不需要搜尋引擎索引,例如將資料匯入 Algolia、Meilisearch 或 Typesense 索引所需的索引。

與資料庫引擎的差異

乍看之下,「資料庫」和「集合」引擎非常相似。它們都直接與您的資料庫互動以檢索搜尋結果。但是,集合引擎不使用全文索引或 LIKE 子句來查找匹配的記錄。相反,它會提取所有可能的記錄,並使用 Laravel 的 Str::is 輔助函數來確定搜尋字串是否存在於模型屬性值中。

集合引擎是最具可移植性的搜尋引擎,因為它適用於 Laravel 支援的所有關係資料庫(包括 SQLite 和 SQL Server);但是,它不如 Scout 的資料庫引擎高效。

索引

批次匯入

如果您正在將 Scout 安裝到現有專案中,您可能已經有需要匯入到索引中的資料庫記錄。Scout 提供了一個 scout:import Artisan 命令,您可以使用它將所有現有記錄匯入到您的搜尋索引中。

php artisan scout:import "App\Models\Post"

flush 命令可用於從您的搜尋索引中刪除模型的所有記錄。

php artisan scout:flush "App\Models\Post"

修改匯入查詢

如果您想修改用於檢索所有模型以進行批次匯入的查詢,您可以在模型上定義 makeAllSearchableUsing 方法。這是新增任何在匯入模型之前可能需要的預先關係載入的好地方。

use Illuminate\Database\Eloquent\Builder;
 
/**
* Modify the query used to retrieve models when making all of the models searchable.
*/
protected function makeAllSearchableUsing(Builder $query): Builder
{
return $query->with('author');
}
exclamation

當使用佇列批次匯入模型時,makeAllSearchableUsing 方法可能不適用。當模型集合由任務處理時,關係不會被恢復

新增記錄

一旦您將 Laravel\Scout\Searchable 特性新增到模型中,您只需 savecreate 一個模型實例,它就會自動新增到您的搜尋索引中。如果您已將 Scout 設定為使用佇列,此操作將由您的佇列工作者在背景中執行。

use App\Models\Order;
 
$order = new Order;
 
// ...
 
$order->save();

透過查詢新增記錄

如果您想透過 Eloquent 查詢將模型集合新增到您的搜尋索引,您可以將 searchable 方法鏈接到 Eloquent 查詢上。searchable 方法將分塊查詢的結果,並將記錄新增到您的搜尋索引中。同樣,如果您已設定 Scout 使用佇列,則所有分塊都將由您的佇列工作者在背景中匯入。

use App\Models\Order;
 
Order::where('price', '>', 100)->searchable();

您也可以在 Eloquent 關係實例上呼叫 searchable 方法。

$user->orders()->searchable();

或者,如果您已經在記憶體中有 Eloquent 模型集合,您可以呼叫集合實例上的 searchable 方法,將模型實例新增到其對應的索引中。

$orders->searchable();
lightbulb

searchable 方法可以被視為「upsert」操作。換句話說,如果模型記錄已在您的索引中,它將被更新。如果它不存在於搜尋索引中,它將被新增到索引中。

更新記錄

要更新可搜尋模型,您只需更新模型實例的屬性並將模型 save 到您的資料庫。Scout 會自動將變更儲存到您的搜尋索引中。

use App\Models\Order;
 
$order = Order::find(1);
 
// Update the order...
 
$order->save();

您也可以在 Eloquent 查詢實例上調用 searchable 方法來更新模型集合。如果模型不存在於您的搜尋索引中,它們將被建立。

Order::where('price', '>', 100)->searchable();

如果您想更新關係中所有模型的搜尋索引記錄,您可以在關係實例上調用 searchable

$user->orders()->searchable();

或者,如果您已經在記憶體中有 Eloquent 模型集合,您可以呼叫集合實例上的 searchable 方法,以更新其對應索引中的模型實例。

$orders->searchable();

在匯入之前修改記錄

有時您可能需要在使模型可搜尋之前準備模型集合。例如,您可能想要預先載入關係,以便可以有效地將關係數據新增到您的搜尋索引中。為此,請在對應的模型上定義 makeSearchableUsing 方法。

use Illuminate\Database\Eloquent\Collection;
 
/**
* Modify the collection of models being made searchable.
*/
public function makeSearchableUsing(Collection $models): Collection
{
return $models->load('author');
}

移除記錄

要從索引中刪除記錄,您可以簡單地從資料庫中 delete 模型。即使您正在使用軟刪除模型,也可以這樣做。

use App\Models\Order;
 
$order = Order::find(1);
 
$order->delete();

如果您不想在刪除記錄之前檢索模型,您可以使用 Eloquent 查詢實例上的 unsearchable 方法。

Order::where('price', '>', 100)->unsearchable();

如果您想刪除關係中所有模型的搜尋索引記錄,您可以在關係實例上調用 unsearchable

$user->orders()->unsearchable();

或者,如果您已經在記憶體中有 Eloquent 模型集合,您可以呼叫集合實例上的 unsearchable 方法,以從其對應的索引中刪除模型實例。

$orders->unsearchable();

要從其對應的索引中刪除模型的所有記錄,您可以調用 removeAllFromSearch 方法。

Order::removeAllFromSearch();

暫停索引

有時您可能需要在不將模型數據同步到搜尋索引的情況下,對模型執行一批 Eloquent 操作。您可以使用 withoutSyncingToSearch 方法來執行此操作。此方法接受單個閉包,該閉包將立即執行。在閉包中發生的任何模型操作都不會同步到模型的索引。

use App\Models\Order;
 
Order::withoutSyncingToSearch(function () {
// Perform model actions...
});

有條件地可搜尋的模型實例

有時您可能需要在特定條件下才使模型可搜尋。例如,假設您有一個 App\Models\Post 模型,該模型可能處於兩種狀態之一:「草稿」和「已發布」。您可能只希望允許「已發布」的文章可搜尋。為此,您可以在模型上定義 shouldBeSearchable 方法。

/**
* Determine if the model should be searchable.
*/
public function shouldBeSearchable(): bool
{
return $this->isPublished();
}

僅當通過 savecreate 方法、查詢或關係操作模型時,才會應用 shouldBeSearchable 方法。直接使用 searchable 方法使模型或集合可搜尋將覆蓋 shouldBeSearchable 方法的結果。

exclamation

當使用 Scout 的「資料庫」引擎時,shouldBeSearchable 方法不適用,因為所有可搜尋的數據始終儲存在資料庫中。要在使用資料庫引擎時實現類似的行為,您應該改用 where 子句

搜尋

您可以使用 search 方法開始搜尋模型。search 方法接受一個單一字串,該字串將用於搜尋您的模型。然後,您應該將 get 方法鏈接到搜尋查詢上,以檢索與給定搜尋查詢匹配的 Eloquent 模型。

use App\Models\Order;
 
$orders = Order::search('Star Trek')->get();

由於 Scout 搜尋返回 Eloquent 模型集合,您甚至可以直接從路由或控制器返回結果,它們將自動轉換為 JSON。

use App\Models\Order;
use Illuminate\Http\Request;
 
Route::get('/search', function (Request $request) {
return Order::search($request->search)->get();
});

如果您想要在搜尋結果轉換為 Eloquent 模型之前取得原始搜尋結果,您可以使用 raw 方法

$orders = Order::search('Star Trek')->raw();

自訂索引

搜尋查詢通常會在模型 searchableAs 方法指定的索引上執行。但是,您可以使用 within 方法來指定應該搜尋的自訂索引

$orders = Order::search('Star Trek')
->within('tv_shows_popularity_desc')
->get();

Where 子句

Scout 允許您在搜尋查詢中加入簡單的 "where" 子句。目前,這些子句僅支援基本的數字相等檢查,主要用於依擁有者 ID 來限定搜尋查詢的範圍

use App\Models\Order;
 
$orders = Order::search('Star Trek')->where('user_id', 1)->get();

此外,whereIn 方法可用於驗證給定欄位的值是否包含在給定的陣列中

$orders = Order::search('Star Trek')->whereIn(
'status', ['open', 'paid']
)->get();

whereNotIn 方法會驗證給定欄位的值是否未包含在給定的陣列中

$orders = Order::search('Star Trek')->whereNotIn(
'status', ['closed']
)->get();

由於搜尋索引不是關聯式資料庫,因此目前不支援更進階的 "where" 子句。

exclamation

如果您的應用程式使用 Meilisearch,您必須先設定應用程式的可篩選屬性,才能使用 Scout 的 "where" 子句。

分頁

除了擷取模型集合之外,您還可以透過使用 paginate 方法來分頁您的搜尋結果。此方法將會返回一個 Illuminate\Pagination\LengthAwarePaginator 實例,就像您對傳統 Eloquent 查詢進行分頁一樣

use App\Models\Order;
 
$orders = Order::search('Star Trek')->paginate();

您可以透過將數量作為 paginate 方法的第一個引數傳遞,來指定每頁要擷取的模型數量

$orders = Order::search('Star Trek')->paginate(15);

一旦您擷取了結果,您可以使用 Blade 顯示結果並呈現頁面連結,就像您對傳統 Eloquent 查詢進行分頁一樣

<div class="container">
@foreach ($orders as $order)
{{ $order->price }}
@endforeach
</div>
 
{{ $orders->links() }}

當然,如果您想以 JSON 格式擷取分頁結果,您可以直接從路由或控制器返回分頁器實例

use App\Models\Order;
use Illuminate\Http\Request;
 
Route::get('/orders', function (Request $request) {
return Order::search($request->input('query'))->paginate(15);
});
exclamation

由於搜尋引擎不知道您的 Eloquent 模型的全域範圍定義,因此您不應在利用 Scout 分頁的應用程式中使用全域範圍。或者,您應該在使用 Scout 搜尋時重新建立全域範圍的約束。

軟刪除

如果您的索引模型是軟刪除的,並且您需要搜尋軟刪除的模型,請將 config/scout.php 組態檔中的 soft_delete 選項設定為 true

'soft_delete' => true,

當此組態選項為 true 時,Scout 不會從搜尋索引中移除軟刪除的模型。相反地,它會在索引的記錄上設定一個隱藏的 __soft_deleted 屬性。然後,您可以使用 withTrashedonlyTrashed 方法在搜尋時擷取軟刪除的記錄

use App\Models\Order;
 
// Include trashed records when retrieving results...
$orders = Order::search('Star Trek')->withTrashed()->get();
 
// Only include trashed records when retrieving results...
$orders = Order::search('Star Trek')->onlyTrashed()->get();
lightbulb

當使用 forceDelete 永久刪除軟刪除的模型時,Scout 會自動從搜尋索引中移除它。

自訂引擎搜尋

如果您需要對引擎的搜尋行為執行進階自訂,您可以將閉包作為 search 方法的第二個引數傳遞。例如,您可以使用此回呼在將搜尋查詢傳遞給 Algolia 之前,將地理位置資料加入到您的搜尋選項中

use Algolia\AlgoliaSearch\SearchIndex;
use App\Models\Order;
 
Order::search(
'Star Trek',
function (SearchIndex $algolia, string $query, array $options) {
$options['body']['query']['bool']['filter']['geo_distance'] = [
'distance' => '1000km',
'location' => ['lat' => 36, 'lon' => 111],
];
 
return $algolia->search($query, $options);
}
)->get();

自訂 Eloquent 結果查詢

在 Scout 從您應用程式的搜尋引擎擷取相符的 Eloquent 模型列表後,Eloquent 會用於通過它們的主鍵擷取所有相符的模型。您可以通過呼叫 query 方法來自訂此查詢。 query 方法接受一個閉包,該閉包將接收 Eloquent 查詢建構器實例作為引數

use App\Models\Order;
use Illuminate\Database\Eloquent\Builder;
 
$orders = Order::search('Star Trek')
->query(fn (Builder $query) => $query->with('invoices'))
->get();

由於此回呼是在從應用程式的搜尋引擎擷取相關模型之後調用的,因此不應將 query 方法用於「篩選」結果。相反地,您應該使用Scout where 子句

自訂引擎

編寫引擎

如果其中一個內建的 Scout 搜尋引擎不符合您的需求,您可以編寫自己的自訂引擎,並將其註冊到 Scout。您的引擎應擴展 Laravel\Scout\Engines\Engine 抽象類別。此抽象類別包含您的自訂引擎必須實作的八個方法

use Laravel\Scout\Builder;
 
abstract public function update($models);
abstract public function delete($models);
abstract public function search(Builder $builder);
abstract public function paginate(Builder $builder, $perPage, $page);
abstract public function mapIds($results);
abstract public function map(Builder $builder, $results, $model);
abstract public function getTotalCount($results);
abstract public function flush($model);

您可能會發現查看 Laravel\Scout\Engines\AlgoliaEngine 類別上這些方法的實作很有幫助。此類別將為您提供一個很好的起點,以了解如何在您自己的引擎中實作這些方法。

註冊引擎

一旦您編寫了自訂引擎,您可以使用 Scout 引擎管理器的 extend 方法將其註冊到 Scout。Scout 的引擎管理器可以從 Laravel 服務容器中解析。您應該從 App\Providers\AppServiceProvider 類別的 boot 方法或應用程式使用的任何其他服務提供者呼叫 extend 方法

use App\ScoutExtensions\MySqlSearchEngine;
use Laravel\Scout\EngineManager;
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
resolve(EngineManager::class)->extend('mysql', function () {
return new MySqlSearchEngine;
});
}

一旦您的引擎註冊完成,您可以在應用程式的 config/scout.php 組態檔中將其指定為預設的 Scout driver

'driver' => 'mysql',