Laravel Scout
Table of Contents
Introduction
Laravel Scout は、Eloquent modelsに全文 search を追加するためのシンプルな、 driver ベースのソリューションを提供します。 model のオブザーバを使用すると、 Scout は自動的にあなたの search インデックスを Eloquent レコードと sync させます。
現在、Scout にはAlgolia 、Meilisearch 、Typesense 、そして MySQL / PostgreSQL(database
)の driver ーが添付されています。さらに、Scout には、ローカル development の使用を意図して設計された"collection"の driver が含まれており、外部の依存関係やサードパーティの services を必要としません。さらに、customdriver ーの作成は簡単で、自身の search の実装で Scout を拡張する自由があります。
Installation
まず、 Composer パッケージマネージャーを使って、 Scout をインストールします:
composer require laravel/scout
Scout をインストールした後、vendor:publish
の Artisan command を使用して Scout の設定ファイルを publish する必要があります。この command は、アプリケーションのconfig
ディレクトリにscout.php
設定ファイルを publish します。
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
最後に、検索可能にしたい model にLaravel\Scout\Searchable
trait を追加してください。この trait は model オブザーバーを register し、 model が自動的にあなたの search driver と sync を保つようにします。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;
class Post extends Model
{
use Searchable;
}
Queueing
Scout を使用するために厳密に必要とされているわけではありませんが、library を使用する前にqueuedriverを設定することを強く検討すべきです。queue ワーカーを実行すると、Scout は model 情報を検索インデックスに同期するすべての操作を queue にすることができ、application の web インターフェースの response 時間を大幅に向上させます。
queue driver を設定したら、config/scout.php
設定ファイルのqueue
オプションの value をtrue
に設定します。
'queue' => true,
queue
オプションがfalse
に設定されている場合でも、Algolia や Meilisearch のような一部の Scout ドライバは常にレコードを非同期でインデックス化することを覚えておくことが重要です。つまり、インデックス操作があなたの Laravel application 内で完了していても、 search エンジン自体は新しく更新されたレコードを即座に反映しないかもしれません。
Scout jobs が使用する connection と queue を指定するには、queue
設定オプションを array として定義することができます。
'queue' => [
'connection' => 'redis',
'queue' => 'scout'
],
もちろん、 Scout jobs が使用する connection や queue をカスタマイズする場合は、その connection および queue 上で queue ワーカーを実行して process jobs を行う必要があります:
php artisan queue:work redis --queue=scout
Driver Prerequisites
Algolia
Algolia の driver を使用するときには、Algolia のid
とsecret
の資格情報をconfig/scout.php
設定ファイルに設定する必要があります。資格情報が設定されたら、さらに Composer パッケージマネージャーを通じて Algolia PHP SDK をインストールする必要があります:
composer require algolia/algoliasearch-client-php
Meilisearch
Meilisearch は驚くほど高速で、オープンソースの検索エンジンです。あなたが自身のローカルマシンに Meilisearch をどのようにインストールするか確信がない場合、Laravel Sail、Laravel の公式にサポートされた Dockerdevelopment 環境を使用することができます。
Meilisearch driver を使用する際には、 Composer パッケージマネージャーを介して Meilisearch PHP SDK をインストールする必要があります:
composer require meilisearch/meilisearch-php http-interop/http-factory-guzzle
次に、アプリケーションの.env
ファイル内にSCOUT_DRIVER
environment 変数と、 Meilisearch のhost
とkey
の認証情報を設定します:
SCOUT_DRIVER=meilisearch
MEILISEARCH_HOST=http://127.0.0.1:7700
MEILISEARCH_KEY=masterKey
Meilisearch に関する詳細は、Meilisearch ドキュメンテーション をご覧ください。
また、meilisearch/meilisearch-php
のバージョンがあなたの Meilisearch binary バージョンと互換性があることを確認するために、binary 互換性についての Meilisearch のドキュメンテーション を確認してインストールするべきです。
WARNING
Meilisearch を使用した application で Scout をアップグレードする際、常に追加の重大な変更 を Meilisearch service 自体でレビューする必要があります。
Typesense
Typesense は非常に高速な open source search エンジンで、キーワード search 、セマンティック search 、ジオ search 、ベクター search をサポートしています。
あなたは Typesense をself-host したり、Typesense Cloud を使用することができます。
Typesense を Scout と一緒に使用を開始するには、 Composer パッケージマネージャーを経由して Typesense PHP SDK をインストールします:
composer require typesense/typesense-php
次に、SCOUT_DRIVER
environment 変数とともに、あなたの Typesense ホストと API キーの認証情報をアプリケーションの.env ファイル内に設定します:
SCOUT_DRIVER=typesense
TYPESENSE_API_KEY=masterKey
TYPESENSE_HOST=localhost
必要に応じて、インストールのポート、 path 、およびプロトコルを指定することもできます:
TYPESENSE_PORT=8108
TYPESENSE_PATH=
TYPESENSE_PROTOCOL=http
あなたの Typesense collections のための追加設定と schema 定義は、あなたのアプリケーションのconfig/scout.php
設定ファイル内で見つけることができます。 Typesense に関する詳細は、Typesense documentation をご覧ください。
Typesense での Data の Storage のための準備
Typesense を利用するとき、検索可能なモデルは、モデルの primary キーを string にキャストし、作成日を UNIX の timestamp にキャストするtoSearchableArray
method を定義する必要があります:
/**
* 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 の collection スキーマを定義する必要があります。 collection schema は、Typesense を介して検索可能な各フィールドの data タイプを説明します。すべての利用可能な schema options に関する詳細情報は、Typesense documentation をご覧ください。
あなたが定義された後で Typesense コレクションの schema を変更する必要がある場合、scout:flush
とscout:import
を実行することができます。これにより、すべての既存のインデックス付けされた data が delete され、 schema が再作成されます。または、Typesense の API を使用して、インデックス付けされた data を削除せずにコレクションの schema を変更することもできます。
あなたの検索可能な model がソフトデリート可能である場合、__soft_deleted
フィールドをモデルの対応する Typesense schema 内のアプリケーションのconfig/scout.php
設定ファイルで定義するべきです:
User::class => [
'collection-schema' => [
'fields' => [
// ...
[
'name' => '__soft_deleted',
'type' => 'int32',
'optional' => true,
],
],
],
],
ダイナミック Search パラメータ
Typesense は、options
method を通じて検索操作を行う際に、検索パラメータ を動的に変更することを可能にします:
use App\Models\Todo;
Todo::search('Groceries')->options([
'query_by' => 'title, description'
])->get();
Configuration
Model インデックスの設定
それぞれの Eloquent model は指定された search index と同期されており、これにはその model の検索可能なすべてのレコードが含まれています。つまり、各インデックスを MySQL のテーブルのように考えることができます。 default では、各 model はモデルの典型的な table 名に一致するインデックスに保持されます。通常、これは model の名前の複数形ですが、 searchableAs
method を model で上書きすることで、モデルのインデックスをカスタマイズすることが自由にできます。
<?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';
}
}
検索可能な Data の設定
default では、指定された model のtoArray
形式全体が、その検索インデックスに保存されます。検索インデックスに同期される data をカスタマイズしたい場合は、model 上のtoSearchableArray
method をオーバーライドすることもできます。
<?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;
}
}
いくつかの search エンジン(例えば、 Meilisearch )は、適切な type の data に対してのみフィルタ操作(>
、<
、 etc 。)を実行します。したがって、これらの search エンジンを使用し、検索可能な data をカスタマイズする場合、数値の values が正しい type にキャストされていることを確認する必要があります。
public function toSearchableArray()
{
return [
'id' => (int) $this->id,
'name' => $this->name,
'price' => (float) $this->price,
];
}
フィルタリング可能な Data とインデックス設定( Meilisearch )の設定
Scout の他のドライバーとは異なり、 Meilisearch は、フィルタリング可能な attributes 、ソート可能な attributes 、およびその他のサポートされる設定フィールド など、インデックス search 設定を事前に定義する必要があります。
Filterable attributes は、Scout の where
method を呼び出す際にフィルタリングする予定のある attributes であり、sortable attributes は、Scout の orderBy
method を呼び出す際に並べ替える予定のある attributes です。インデックス設定を定義するには、アプリケーションの scout
設定ファイル内の meilisearch
設定エントリの index-settings
部分を調整します。
use App\Models\User;
use App\Models\Flight;
'meilisearch' => [
'host' => env('MEILISEARCH_HOST', 'http://localhost: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'],
],
],
],
指定されたインデックスの基となる model がソフト削除可能であり、index-settings
array に含まれている場合、 Scout はそのインデックス上のソフト削除された models に対するフィルタリングのサポートを自動的に含みます。ソフト削除可能な model のインデックスに対して定義する他のフィルタリング可能またはソート可能な attributes がない場合、その model に対するindex-settings
array に空のエントリを追加するだけでよいです:
'index-settings' => [
Flight::class => []
],
あなたのアプリケーションのインデックス設定を設定した後、scout:sync-index-settings
Artisan command を呼び出す必要があります。この command は、現在設定されているインデックス設定を Meilisearch に通知します。便宜上、この command を deployment process の一部にすることをお勧めします:
php artisan scout:sync-index-settings
Model ID の設定
default として、Scout は、model の primarykey を、search インデックスに格納される model の unique な ID / key として使用します。この挙動をカスタマイズする必要がある場合、model 上でgetScoutKey
methods とgetScoutKeyName
methods をオーバーライドすることができます。
<?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';
}
}
Model ごとの Search エンジンの設定
検索時、Scout は通常、あなたの application のscout
設定ファイルで指定された default の検索エンジンを使用します。ただし、特定の model の検索エンジンは、model 上のsearchableUsing
method を上書きすることで変更することができます:
<?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');
}
}
Users の特定
Scout は、Algolia を使用する際に user を自動認識することも可能です。authentication 済みの user を検索操作と関連付けることは、Algolia のダッシュボード内で検索分析を表示する際に役立つかもしれません。 SCOUT_IDENTIFY
環境 variable を application の.env
ファイル内でtrue
として定義することで、user の識別を有効にすることができます。
SCOUT_IDENTIFY=true
この feature を有効にすると、リクエストの IP アドレスと認証済みユーザーの primary 識別子も Algolia に渡され、この data が user が行うあらゆる search request に関連付けられます。
Database / Collection Engines
Database エンジン
WARNING
現在の database エンジンは MySQL と PostgreSQL をサポートしています。
あなたの application が中小規模の database と対話を行うか、軽い作業量を持つ場合、Scout の"database"エンジンを使い始める方が便利かもしれません。 database エンジンは、既存の database からフィルタリングされた結果を決定する際に、"where like"の節と全文インデックスを使用し、適用可能な search 結果をあなたの query に決定します。
database エンジンを使用するには、SCOUT_DRIVER
environment 変数の value を database
に設定するか、アプリケーションの scout
設定ファイルで database
driver を直接指定します。
SCOUT_DRIVER=database
`database エンジンを好みの driver として指定した後、検索可能な data を設定する必要があります。その後、models に対して search query を実行することができます。database エンジンを利用している場合、Algolia、Meilisearch、または Typesense インデックスに必要なインデクシング、例えば seed のためのインデクシングは不要です。
Database 検索戦略のカスタマイズ
default では、database エンジンは、検索可能に設定した全ての model 属性に対して where like query を実行します。しかし、場合によっては、これがパフォーマンスの低下につながることがあります。従って、database エンジンの検索戦略は、一部の指定された列がフルテキスト検索 query を利用したり、where like 制約を使用して string の接頭辞(example%
)のみを検索したりするように設定できます。これは、string 全体を検索する(%example%
)のではなく、接頭辞のみを検索することを意味します。
この動作を定義するには、モデルの toSearchableArray
method に PHP の attributes を割り当てることができます。追加の search 戦略行動が割り当てられていない任意の列は、 default の"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,
];
}
WARNING
column に全文テキストの query 制約を使用するよう指定する前に、その column に全文インデックスが割り当てられていることを確認してください。
Collection エンジン
ローカル開発中に Algolia、 Meilisearch 、または Typesense の search エンジンを自由に使用しても構いませんが、 query エンジンを始める方が便利かもしれません。 collection エンジンでは、where 節と collection フィルタリングを使用して、既存の database からの結果を元に該当する search 結果を判断します。このエンジンを使用するとき、検索可能な models を index する必要はありません。なぜなら、それらは単にローカルの database から retrieved されるだけだからです。
collection エンジンを使用するには、SCOUT_DRIVER
environment 変数の value を collection
に設定するか、アプリケーションの scout
設定ファイルで collection
driver を直接指定します。
SCOUT_DRIVER=collection
collection driver を適用する driver として指定すると、 models に対してSearch クエリの実行を開始できます。 Algolia、 Meilisearch 、または Typesense のインデックスに seed を必要とするような、 search エンジンのインデックス作成は、 collection エンジンを使用する場合には不要です。
Database エンジンとの違い
初めて見たとき、"database"と"collections"のエンジンはかなり似ています。どちらも直接あなたの database と対話して search の結果を取得します。しかし、collection エンジンは、一致するレコードを見つけるために全文インデックスやLIKE
句を利用しません。代わりに、可能な全てのレコードを引っ張り、Laravel の Str::is
ヘルパを使用して、search string が model attribute values 内に存在するかどうかを判断します。
collection エンジンは、 Laravel がサポートするすべてのリレーショナルデータベース(SQLite や SQL Server を含む)で動作するため、最も移植性の高い search エンジンです。しかしながら、Scout の database エンジンに比べて効率は劣ります。
Indexing
Batch インポート
既存の project に Scout をインストールしている場合、インデックスにインポートする必要がある database レコードが既にあるかもしれません。 Scout は、既存のすべてのレコードを search インデックスにインポートするために使用することができる scout:import
Artisan command を提供します:
php artisan scout:import "App\Models\Post"
flush
command は model の全レコードをあなたの search インデックスから削除するために使用できます:
php artisan scout:flush "App\Models\Post"
インポートの Query を変更する
batch インポート用にすべての models を取得するために使用される query を変更したい場合は、 model にmakeAllSearchableUsing
method を定義することができます。これは、 models `をインポートする前に必要な、任意のイーガーリレーションシップのロードを追加するのに適した場所です。
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');
}
WARNING
makeAllSearchableUsing
method は、 queue を使用して models を batch インポートする際に適用できない場合があります。 model collections が jobs によって処理されると、リレーションシップは復元されません。
レコードを追加する
Laravel\Scout\Searchable
トレイトを model に追加したら、あとは save
するか、 create
で model のインスタンスを作成するだけで、自動的に検索インデックスに追加されます。Scout をqueues を使用するために設定している場合、この操作は queues ワーカーによりバックグラウンドで実行されます。
use App\Models\Order;
$order = new Order;
// ...
$order->save();
レコードを Query を使って追加する
Eloquent query を通じて models の collection を 検索インデックスに追加したい場合は、searchable
method を Eloquentquery にチェーンさせることができます。searchable
method は query の結果をchunkにし、それらのレコードを検索インデックスに追加します。なお、Scout を queues を使用するように設定した場合、すべての chunk は queues ワーカーによりバックグラウンドでインポートされます。
use App\Models\Order;
Order::where('price', '>', 100)->searchable();
また、 Eloquent 関係のインスタンスで searchable
method を呼び出すこともできます:
$user->orders()->searchable();
または、すでにメモリに Eloquent models の collection を持っている場合、searchable
method を collection インスタンス上で呼び出して、 model インスタンスを対応するインデックスに追加することもできます:
$orders->searchable();
NOTE
searchable
method は、upsert 操作と見なすことができます。つまり、もし model のレコードがすでにインデックスに存在する場合、それは更新されます。もし search のインデックスに存在しない場合、それはインデックスに追加されます。
レコードの更新
検索可能な model を update するには、 model インスタンスのプロパティを update し、その model をあなたの database にsave
するだけでよいです。 Scout は自動的にあなたの search インデックスに変更を持続させます。
use App\Models\Order;
$order = Order::find(1);
// Update the order...
$order->save();
また、searchable
の method を Eloquent query インスタンスに呼び出して、models の collection を更新することもできます。もし models があなたの検索インデックスに存在しない場合、それらは作成されます:
Order::where('price', '>', 100)->searchable();
関連付けられた全ての models の search インデックスレコードを update したい場合は、関連付けのインスタンスで searchable
を呼び出すことができます:
$user->orders()->searchable();
また、すでにメモリー上に Eloquent models の collection がある場合は、searchable
method を collection インスタンスで呼び出し、それぞれのインデックスにある model インスタンスを update することもできます。
$orders->searchable();
インポート前のレコードの修正
時折、 models が検索可能になる前に、それらの collection を準備する必要があります。例えば、関連付けを事前に読み込んで、関連付けの data が効率的に search インデックスに追加できるようにすることができます。これを実現するためには、対応する model 上にmakeSearchableUsing
method を定義します:
use Illuminate\Database\Eloquent\Collection;
/**
* Modify the collection of models being made searchable.
*/
public function makeSearchableUsing(Collection $models): Collection
{
return $models->load('author');
}
レコードの削除
インデックスからレコードを削除するには、単純に delete
で model を database から削除します。これは、あなたが論理削除の models を使用している場合でも行うことができます:
use App\Models\Order;
$order = Order::find(1);
$order->delete();
レコードを削除する前に model を取得したくない場合は、unsearchable
method を Eloquent query インスタンスで使用することができます:
Order::where('price', '>', 100)->unsearchable();
もし関係性にある全ての models の search インデックス記録を削除したい場合、関係性インスタンスでunsearchable
を呼び出すことができます:
$user->orders()->unsearchable();
また、すでにメモリに Eloquent models の collection がある場合は、その collection インスタンスで unsearchable
method を呼び出し、各 model インスタンスを対応するインデックスから削除することができます。
$orders->unsearchable();
インデックス作成の一時停止
時々、model の modeldata を検索インデックスに同期せずに、 model 上で一連の Eloquent 操作を実行する必要があるかもしれません。これは、withoutSyncingToSearch
method を使用して行うことができます。この method は単一のクロージャを受け入れ、すぐに実行されます。クロージャ内で発生する任意の model 操作は、model のインデックスに同期されません:
use App\Models\Order;
Order::withoutSyncingToSearch(function () {
// Perform model actions...
});
条件付き検索可能な Model インスタンス
時々、特定の条件下でのみ model を検索可能にしたいことがあります。たとえば、App\Models\Post
model が下書きもしくは公開済みの二つの状態であることを想像してみてください。"公開済み"の投稿のみを検索可能にしたい場合があります。この場合、shouldBeSearchable
method をあなたの model で定義することでこれを実現できます。
/**
* Determine if the model should be searchable.
*/
public function shouldBeSearchable(): bool
{
return $this->isPublished();
}
shouldBeSearchable
method は、save
やcreate
メソッド、query、またはリレーションシップを通じて models を操作する場合にのみ適用されます。searchable
method を使用して直接 models や collections を検索可能にすると、shouldBeSearchable
method の結果が上書きされます。
WARNING
shouldBeSearchable
method は、Scout の Database エンジンを使用する際には適用できません。なぜなら、すべての検索可能な data は常に database に保存されているからです。同様の振る舞いを Database エンジンを使用して達成するためには、代わりにwhere 節を使用すべきです。
Searching
search
の method を使用して、 model の検索を開始できます。 search method は、あなたの models を search するために使用する single string を受け入れます。次に、与えられた search query に match する Eloquent models を取得するために、get
の method を search query に連鎖させる必要があります。
use App\Models\Order;
$orders = Order::search('Star Trek')->get();
Scout の検索結果は Eloquent models の collection を返すので、結果を直接 route や controller から返すこともできます。それらは自動的に JSON に変換されます:
use App\Models\Order;
use Illuminate\Http\Request;
Route::get('/search', function (Request $request) {
return Order::search($request->search)->get();
});
もしあなたが Eloquent models に変換される前の生の search 結果を取得したい場合は、raw
method を使用することができます:
$orders = Order::search('Star Trek')->raw();
Custom インデックス
Search クエリは、通常、モデルのsearchableAs
method で指定されたインデックスで実行されます。しかし、within
method を使用して、代わりに検索するべき custom インデックスを指定することもできます。
$orders = Order::search('Star Trek')
->within('tv_shows_popularity_desc')
->get();
Where Clauses
Scout は、"where"句をあなたの search クエリに簡単に追加することができます。現在、これらの句は基本的な数値の等価性チェックのみをサポートしており、所有者 ID による search クエリのスコープ設定に主に役立ちます:
use App\Models\Order;
$orders = Order::search('Star Trek')->where('user_id', 1)->get();
さらに、whereIn
の method は、与えられたカラムの value が指定された array 内に含まれていることを確認するために使用することができます:
$orders = Order::search('Star Trek')->whereIn(
'status', ['open', 'paid']
)->get();
The whereNotIn
method verifies that the given column's value is not contained in the given array:
$orders = Order::search('Star Trek')->whereNotIn(
'status', ['closed']
)->get();
search インデックスはリレーショナル database ではないため、現在 where 句のような高度な機能はサポートされていません。
WARNING
あなたの application が Meilisearch を使用している場合、Scout の"where"節を利用する前に、アプリケーションのフィルタリング可能な attributesを設定する必要があります。
Pagination
models の collection を取得するだけでなく、paginate
method を使用して検索結果をページネートすることができます。この method は、伝統的な Eloquent query をページネートしたかのように、Illuminate\Pagination\LengthAwarePaginator
インスタンスを返します。
use App\Models\Order;
$orders = Order::search('Star Trek')->paginate();
ページごとに取得する models の数を指定することができます。これは、paginate
method に第一引数として渡すことで実現可能です:
$orders = Order::search('Star Trek')->paginate(15);
結果を retrieved したら、Bladeを使ってまるで伝統的な Eloquent query をページ化したかのように、結果を表示し、 links ページを render することができます。
<div class="container">
@foreach ($orders as $order) {{ $order->price }} @endforeach
</div>
{{ $orders->links() }}
もちろん、 pagination の結果を JSON として取得したい場合は、 route または controller から直接 paginator インスタンスを返すことができます。
use App\Models\Order;
use Illuminate\Http\Request;
Route::get('/orders', function (Request $request) {
return Order::search($request->input('query'))->paginate(15);
});
WARNING
search エンジンは、あなたの Eloquent モデルのグローバルな scope 定義を認識しないので、 Scout pagination を使用するアプリケーションでグローバルスコープを使用すべきではありません。あるいは、 Scout で検索する際に、グローバルスコープの制約を再作成する必要があります。
Soft Deleting
config/scout.php
の構成ファイルで soft_delete
オプションを true
に設定することで、インデックス化された models がsoft deletingであり、ソフト削除された models を search する必要がある場合:
'soft_delete' => true,
この設定オプションが true
の場合、 Scout は models からソフト削除されたアイテムを search インデックスから削除しません。代わりに、インデックス化されたレコードに hidden __soft_deleted
attribute を設定します。その後で、検索時にソフト削除されたレコードを取得するために、 withTrashed
メソッドまたは onlyTrashed
メソッドを使用することができます。
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();
NOTE
ソフトに削除された model が
forceDelete
を使用して完全に削除されると、 Scout はそれを自動的に search インデックスから削除します。
エンジン検索のカスタマイズ
エンジンの search 動作の高度なカスタマイゼーションを行う必要がある場合は、search
method の 2 つ目の引数としてクロージャを渡すことができます。たとえば、このコールバックを使用して、 search query が Algolia に渡される前に、ジオロケーション data を search options に追加することができます。
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 結果の Query をカスタマイズする
Scout があなたのアプリケーションの search エンジンから一致する Eloquent models のリストを取得した後、 Eloquent はそれらの一致する models をそれらの primary keys によって全て取得するために使用されます。あなたはこのquery
method を呼び出すことでこの query をカスタマイズすることができます。query
method は、引数として Eloquent query ビルダーインスタンスを受け取るクロージャを受け入れます:
use App\Models\Order;
use Illuminate\Database\Eloquent\Builder;
$orders = Order::search('Star Trek')
->query(fn (Builder $query) => $query->with('invoices'))
->get();
このコールバックは、あなたのアプリケーションの search エンジンから既に retrieved された関連する models の後に呼び出されるため、query
method は結果の"フィルタリング"に使用すべきではありません。代わりに、Scout where clausesを使用すべきです。
Custom Engines
エンジンの作成
もし組み込みの Scout search エンジンがあなたのニーズに合わない場合、あなた自身の custom エンジンを書き、それを Scout に register することができます。あなたのエンジンは Laravel\Scout\Engines\Engine
抽象 class を拡張するべきです。この抽象 class には、あなたの custom エンジンが実装しなければならない 8 つのメソッドが含まれています:
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);
これらの methods の実装をレ view すると便利かもしれません。それらは Laravel\Scout\Engines\AlgoliaEngine
class にあります。この class は、自分のエンジンでこれらの methods を実装する方法を学ぶのに良いスタートポイントとなるでしょう。
エンジンの登録
あなたが custom エンジンを記述し終えたら、それをextend
method を使って Scout に register することができます。 Scout のエンジンマネージャは、 Laravel service container から解決することができます。extend
method は、あなたのApp\Providers\AppServiceProvider
class のboot
method や、あなたの application が使用している他の service provider から呼び出すべきです:
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
設定ファイルで、それをデフォルトの default Scout driver
として指定することができます:
'driver' => 'mysql',