メインコンテンツまでスキップ
バージョン: 12.x

Laravel Scout

Introduction

Laravel Scout は、Eloquent models に全文検索を追加するためのシンプルなドライバベースのソリューションを提供します。 Scout はモデル オブザーバを使用して、検索インデックスを Eloquent レコードと自動的に同期させます。

Scout には、MySQL / PostgreSQL フルテキスト インデックスと LIKE 句を使用して既存のデータベースを検索する組み込みの database エンジンが付属しており、外部サービスは必要ありません。ほとんどのアプリケーションで必要なのはこれだけです。 Laravel で利用可能なすべての検索オプションの概要については、search documentation を参照してください。

Scout には、タイプミス耐性、ファセット フィルター、大規模な地域検索などの機能が必要な場合に備えて、AlgoliaMeilisearchTypesense のドライバも含まれています。 「コレクション」ドライバもローカル開発に使用でき、custom engines も自由に作成できます。

Installation

まず、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;
}

Queueing

database エンジンまたは collection エンジンではないエンジンを使用する場合は、ライブラリを使用する前に queue driver を構成することを強く検討する必要があります。キューワーカーを実行すると、Scout はモデル情報を検索インデックスに同期するすべての操作をキューに入れることができるため、アプリケーションの Web インターフェイスの応答時間が大幅に向上します。

キュードライバを構成したら、config/scout.php 構成ファイルの queue オプションの値を true に設定します。

'queue' => true,

queue オプションが false に設定されている場合でも、Algolia や Meil​​isearch などの一部の Scout ドライバは常に非同期でレコードのインデックスを作成することに留意することが重要です。言い換えれば、Laravel アプリケーション内でインデックス操作が完了したとしても、検索エンジン自体には新しいレコードや更新されたレコードがすぐに反映されない可能性があります。

Scout ジョブが使用する接続とキューを指定するには、queue 構成オプションを配列として定義できます。

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

もちろん、Scout ジョブが使用する接続とキューをカスタマイズする場合は、キューワーカーを実行して、その接続とキューでジョブを処理する必要があります。

php artisan queue:work redis --queue=scout

Driver Prerequisites

Algolia

Algolia ドライバを使用する場合は、config/scout.php 構成ファイルで Algolia id および secret 資格情報を構成する必要があります。認証情報を設定したら、Composer パッケージ マネージャーを介して Algolia PHP SDK をインストールする必要もあります。

composer require algolia/algoliasearch-client-php

Meilisearch

Meilisearch は、高速なオープンソースの検索エンジンです。 Meilisearch をローカル マシンにインストールする方法がわからない場合は、Laravel が公式にサポートする Docker 開発環境である Laravel Sail を使用できます。

Meilisearch ドライバを使用する場合は、Composer パッケージ マネージャーを介して Meil​​isearch PHP SDK をインストールする必要があります。

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

次に、アプリケーションの .env ファイル内で、SCOUT_DRIVER 環境変数と Meil​​isearch host および key 資格情報を設定します。

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

Meilisearch の詳細については、Meilisearch documentation を参照してください。

さらに、Meilisearch's documentation regarding binary compatibility を確認して、Meilisearch バイナリ バージョンと互換性のある meilisearch/meilisearch-php のバージョンをインストールしていることを確認する必要があります。

Meilisearch を利用するアプリケーションで Scout をアップグレードする場合は、常に Meil​​isearch サービス自体に review any additional breaking changes を実行する必要があります。

Typesense

Typesense は超高速のオープンソース検索エンジンで、キーワード検索、セマンティック検索、地理検索、ベクトル検索をサポートしています。

self-host Typesense または Typesense Cloud を使用できます。

Scout で Typesense の使用を開始するには、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 を使用している場合は、Docker コンテナー名と一致するように TYPESENSE_HOST 環境変数を調整する必要がある場合があります。オプションで、インストールのポート、パス、プロトコルを指定することもできます。

TYPESENSE_PORT=8108
TYPESENSE_PATH=
TYPESENSE_PROTOCOL=http

Typesense コレクションの追加の設定とスキーマ定義は、アプリケーションの config/scout.php 構成ファイル内にあります。 Typesense の詳細については、Typesense documentation を参照してください。

Configuration

Configuring Searchable Data

デフォルトでは、特定のモデルの 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;
}
}

Configuring Model Engines

検索する場合、Scout は通常、アプリケーションの scout 構成ファイルで指定されたデフォルトの検索エンジンを使用します。ただし、特定のモデルの検索エンジンは、モデルの searchableUsing メソッドをオーバーライドすることで変更できます。

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Engines\Engine;
use Laravel\Scout\Scout;
use Laravel\Scout\Searchable;

class User extends Model
{
use Searchable;

/**
* Get the engine used to index the model.
*/
public function searchableUsing(): Engine
{
return Scout::engine('meilisearch');
}
}

Database / Collection Engines

Database Engine

データベース エンジンは現在、MySQL と PostgreSQL をサポートしており、どちらも高速な全文列インデックス作成をサポートします。

database エンジンは、MySQL / PostgreSQL フルテキスト インデックスと LIKE 句を使用して、既存のデータベースを直接検索します。多くのアプリケーションにとって、これは検索を追加する最も簡単で実用的な方法であり、外部サービスや追加のインフラストラクチャは必要ありません。

データベース エンジンを使用するには、SCOUT_DRIVER 環境変数を database に設定します。

SCOUT_DRIVER=database

構成が完了したら、define your searchable data を実行し、モデルに対して executing search queries を開始できます。サードパーティ エンジンとは異なり、データベース エンジンは個別のインデックス作成手順を必要とせず、データベース テーブルを直接検索します。

Customizing Database Searching Strategies

デフォルトでは、データベース エンジンは、configured as searchable を持つすべてのモデル属性に対して LIKE クエリを実行します。ただし、より効率的な検索戦略を特定の列に割り当てることができます。 SearchUsingFullText 属性はその列に対してデータベースのフルテキスト インデックスを使用しますが、SearchUsingPrefix は文字列全体 (%example%) 内を検索するのではなく、文字列の先頭 (example%) のみに一致します。

この動作を定義するには、モデルの toSearchableArray メソッドに PHP 属性を割り当てます。属性のない列は、引き続きデフォルトの 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,
];
}

列でフルテキスト クエリ制約を使用するように指定する前に、列に full text index が割り当てられていることを確認してください。

Collection Engine

「コレクション」エンジンは、迅速なプロトタイプ、非常に小さなデータセット (数百レコード)、またはテストの実行を目的としています。データベースからすべての可能なレコードを取得し、Laravel の Str::is ヘルパを使用してそれらを PHP でフィルタリングするため、インデックス作成やデータベース固有の機能は必要ありません。些細な使用例を超える場合は、代わりに database engine を使用する必要があります。

収集エンジンを使用するには、単に SCOUT_DRIVER 環境変数の値を collection に設定するか、アプリケーションの scout 構成ファイルで collection ドライバを直接指定します。

SCOUT_DRIVER=collection

コレクション ドライバを優先ドライバとして指定したら、モデルに対して executing search queries を開始できます。コレクション エンジンを使用する場合、Algolia、Meilisearch、または Typesense インデックスのシードに必要なインデックス作成などの検索エンジンのインデックス作成は不要です。

Differences From Database Engine

データベース エンジンはフルテキスト インデックスと LIKE 句を使用して一致するレコードを効率的に検索しますが、コレクション エンジンはすべてのレコードを取得し、PHP でフィルタリングします。コレクション エンジンは、Laravel でサポートされるすべてのリレーショナル データベース (SQLite および SQL Server を含む) で動作するため、最も移植性の高いオプションです。ただし、データベース エンジンよりも効率が大幅に低いため、大規模なデータセットでは使用しないでください。

Third-Party Engine Configuration

次の構成オプションは、Algolia、Meilisearch、Typesense などのサードパーティの検索エンジンを使用する場合にのみ関係します。 database engine を使用している場合は、このセクションをスキップしてください。

Configuring Model Indexes

サードパーティ エンジンを使用する場合、各 Eloquent モデルは、そのモデルの検索可能なすべてのレコードを含む特定の検索「インデックス」と同期されます。デフォルトでは、各モデルは、モデルの一般的な「テーブル」名に一致するインデックスに保存されます。通常、これはモデル名の複数形です。ただし、モデルの 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';
}
}

searchableAs メソッドは、常にモデルのデータベース テーブルを直接検索するデータベース エンジンを使用する場合には効果がありません。

Configuring the Model ID

デフォルトでは、Scout はモデルの主キーを、検索インデックスに保存されるモデルの一意の ID/キーとして使用します。サードパーティ エンジンの使用時にこの動作をカスタマイズする必要がある場合は、モデルの getScoutKey メソッドと getScoutKeyName メソッドをオーバーライドできます。

<?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';
}
}

getScoutKey メソッドと getScoutKeyName メソッドは、常にモデルの主キーを使用するデータベース エンジンを使用する場合には効果がありません。

Algolia

Index Settings

Algolia インデックスに追加の設定を構成することが必要になる場合があります。これらの設定は Algolia UI を介して管理できますが、場合によっては、アプリケーションの config/scout.php 構成ファイルから直接、インデックス構成の望ましい状態を管理する方が効率的です。

このアプローチにより、アプリケーションの自動展開パイプラインを通じてこれらの設定を展開できるため、手動による構成が回避され、複数の環境間での一貫性が確保されます。フィルター可能な属性、ランキング、ファセット、または any other supported settings を構成できます。

まず、アプリケーションの config/scout.php 構成ファイルに各インデックスの設定を追加します。

use App\Models\User;
use App\Models\Flight;

'algolia' => [
'id' => env('ALGOLIA_APP_ID', ''),
'secret' => env('ALGOLIA_SECRET', ''),
'index-settings' => [
User::class => [
'searchableAttributes' => ['id', 'name', 'email'],
'attributesForFaceting'=> ['filterOnly(email)'],
// Other settings fields...
],
Flight::class => [
'searchableAttributes'=> ['id', 'destination'],
],
],
],

特定のインデックスの基礎となるモデルが論理的に削除可能で、index-settings 配列に含まれている場合、Scout はそのインデックス上の論理的に削除されたモデルのファセットのサポートを自動的に組み込みます。ソフト削除可能なモデル インデックスに対して定義する他のファセット属性がない場合は、そのモデルの index-settings 配列に空のエントリを追加するだけで済みます。

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

アプリケーションのインデックス設定を構成した後、scout:sync-index-settings Artisan コマンドを呼び出す必要があります。このコマンドは、現在構成されているインデックス設定を Algolia に通知します。便宜上、このコマンドを展開プロセスの一部にするとよいでしょう。

php artisan scout:sync-index-settings

Identifying Users

Scout を使用すると、Algolia の使用時にユーザーを自動識別できます。認証されたユーザーを検索操作に関連付けると、Algolia のダッシュボード内で検索分析を表示するときに役立つ場合があります。ユーザー識別を有効にするには、アプリケーションの .env ファイルで SCOUT_IDENTIFY 環境変数を true として定義します。

SCOUT_IDENTIFY=true

この機能を有効にすると、リクエストの IP アドレスと認証されたユーザーのプライマリ識別子も Algolia に渡されるため、このデータはユーザーが行った検索リクエストに関連付けられます。

Meilisearch

Index Settings

Meilisearch では、フィルター可能な属性、並べ替え可能な属性、other supported settings fields などのインデックス検索設定を事前に定義する必要があります。

フィルター可能な属性は、Scout の where メソッドを呼び出すときにフィルター処理する予定の属性であり、並べ替え可能な属性は、Scout の orderBy メソッドを呼び出すときに並べ替える予定の属性です。インデックス設定を定義するには、アプリケーションの 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'],
],
],
],

特定のインデックスの基礎となるモデルが論理的に削除可能で、index-settings 配列に含まれている場合、Scout はそのインデックス上の論理的に削除されたモデルのフィルター処理のサポートを自動的に組み込みます。ソフト削除可能なモデル インデックスに対して定義するフィルター可能または並べ替え可能な属性が他にない場合は、そのモデルの index-settings 配列に空のエントリを追加するだけで済みます。

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

アプリケーションのインデックス設定を構成した後、scout:sync-index-settings Artisan コマンドを呼び出す必要があります。このコマンドは、Meilisearch に現在構成されているインデックス設定を通知します。便宜上、このコマンドを展開プロセスの一部にするとよいでしょう。

php artisan scout:sync-index-settings

Searchable Data Types

Meilisearch は、正しいタイプのデータに対してフィルター操作 (>< など) のみを実行します。検索可能なデータをカスタマイズするときは、数値が正しい型にcastされていることを確認する必要があります。

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

Typesense

Preparing Searchable Data

Typesense を利用する場合、検索可能なモデルは、モデルの主キーを文字列にcastし、作成日を UNIX タイムスタンプにcastする toSearchableArray メソッドを定義する必要があります。

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

また、アプリケーションの config/scout.php ファイルで Typesense コレクション スキーマを定義する必要があります。コレクション スキーマは、Typesense を介して検索可能な各フィールドのデータ型を記述します。利用可能なすべてのスキーマ オプションの詳細については、Typesense documentation を参照してください。

Typesense コレクションのスキーマを定義した後に変更する必要がある場合は、scout:flush および scout:import を実行します。これにより、既存のインデックス付きデータがすべて削除され、スキーマが再作成されます。または、Typesense の API を使用して、インデックス付きデータを削除せずにコレクションのスキーマを変更することもできます。

検索可能なモデルが論理的に削除可能な場合は、アプリケーションの config/scout.php 構成ファイル内のモデルに対応する Typesense スキーマで __soft_deleted フィールドを定義する必要があります。

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

Dynamic Search Parameters

Typesense を使用すると、options メソッド経由で検索操作を実行するときに、search parameters を動的に変更できます。

use App\Models\Todo;

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

Third-Party Engine Indexing

このセクションで説明するインデックス作成機能は、主にサードパーティ エンジン (Algolia、Meilisearch、または Typesense) を使用する場合に関係します。データベース エンジンはデータベース テーブルを直接検索するため、手動でインデックスを管理する必要はありません。

Batch Import

既存のプロジェクトに Scout をインストールする場合は、インデックスにインポートする必要があるデータベース レコードがすでに存在する可能性があります。 Scout は、既存のすべてのレコードを検索インデックスにインポートするために使用できる scout:import Artisan コマンドを提供します。

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

scout:queue-import コマンドを使用すると、queued jobs を使用して既存のレコードをすべてインポートできます。

php artisan scout:queue-import "App\Models\Post" --chunk=500

flush コマンドを使用して、モデルのすべてのレコードを検索インデックスから削除できます。

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

Modifying the Import Query

バッチインポート用にすべてのモデルを取得するために使用されるクエリを変更したい場合は、モデルに 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');
}

makeAllSearchableUsing メソッドは、キューを使用してモデルをバッチ インポートする場合には適用できない場合があります。モデル コレクションがジョブによって処理される場合、関係は not restored になります。

Adding Records

Laravel\Scout\Searchable トレイトをモデルに追加したら、モデル インスタンスに save または create を追加するだけで、検索インデックスに自動的に追加されます。 Scout を use queues に構成した場合、この操作はキューワーカーによってバックグラウンドで実行されます。

use App\Models\Order;

$order = new Order;

// ...

$order->save();

Adding Records via Query

Eloquent クエリを介してモデルのコレクションを検索インデックスに追加したい場合は、searchable メソッドを Eloquent クエリにチェーンできます。 searchable メソッドは、クエリの chunk the results を実行し、レコードを検索インデックスに追加します。繰り返しますが、キューを使用するように Scout を構成している場合、すべてのチャンクがキューワーカーによってバックグラウンドでインポートされます。

use App\Models\Order;

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

Eloquent リレーションシップ インスタンスで searchable メソッドを呼び出すこともできます。

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

または、メモリ内に Eloquent モデルのコレクションがすでにある場合は、コレクション インスタンスで searchable メソッドを呼び出して、モデル インスタンスを対応するインデックスに追加することもできます。

$orders->searchable();

searchable メソッドは、「upsert」操作とみなすことができます。つまり、モデル レコードがすでにインデックスに存在する場合、それは更新されます。検索インデックスに存在しない場合は、インデックスに追加されます。

Updating Records

検索可能なモデルを更新するには、モデル インスタンスのプロパティとデータベースのモデルを 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();

Modifying Records Before Importing

場合によっては、モデルのコレクションを検索可能にする前に準備する必要がある場合があります。たとえば、関係データを検索インデックスに効率的に追加できるように、関係を一括ロードすることができます。これを実現するには、対応するモデルで makeSearchableUsing メソッドを定義します。

use Illuminate\Database\Eloquent\Collection;

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

Conditionally Updating the Search Index

デフォルトでは、Scout は、どの属性が変更されたかに関係なく、更新されたモデルのインデックスを再作成します。この動作をカスタマイズしたい場合は、モデルに searchIndexShouldBeUpdated メソッドを定義できます。

/**
* Determine if the search index should be updated.
*/
public function searchIndexShouldBeUpdated(): bool
{
return $this->wasRecentlyCreated || $this->wasChanged(['title', 'body']);
}

Removing Records

インデックスからレコードを削除するには、データベースからモデルを delete するだけです。これは、soft deleted モデルを使用している場合でも実行できます。

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();

Pausing Indexing

場合によっては、モデル データを検索インデックスに同期せずに、モデルに対して Eloquent 操作のバッチを実行する必要がある場合があります。これは、withoutSyncingToSearch メソッドを使用して行うことができます。このメソッドは、ただちに実行される単一のクロージャを受け入れます。クロージャ内で発生するモデル操作はモデルのインデックスに同期されません。

use App\Models\Order;

Order::withoutSyncingToSearch(function () {
// Perform model actions...
});

Conditionally Searchable Model Instances

場合によっては、特定の条件下でのみモデルを検索可能にすることが必要な場合があります。たとえば、「ドラフト」と「公開」の 2 つの状態のいずれかにある App\Models\Post モデルがあるとします。 「公開された」投稿のみを検索可能にしたい場合があります。これを実現するには、モデルに shouldBeSearchable メソッドを定義します。

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

shouldBeSearchable メソッドは、save および create メソッド、クエリ、または関係を通じてモデルを操作する場合にのみ適用されます。 searchable メソッドを使用してモデルまたはコレクションを直接検索可能にすると、shouldBeSearchable メソッドの結果がオーバーライドされます。

検索可能なすべてのデータは常にデータベースに保存されるため、Scout の「データベース」エンジンを使用する場合、shouldBeSearchable メソッドは適用できません。データベース エンジンを使用するときに同様の動作を実現するには、代わりに where clauses を使用する必要があります。

Searching

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();

Custom Indexes

サードパーティ エンジンを使用して検索する場合、通常、検索クエリはモデルの searchableAs メソッドで指定されたインデックスに対して実行されます。ただし、代わりに within メソッドを使用して、検索するカスタム インデックスを指定することもできます。

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

Where Clauses

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();

アプリケーションが Meil​​isearch を使用している場合は、Scout の「where」句を使用する前に、アプリケーションの filterable attributes を構成する必要があります。

Customizing the Eloquent Results Query

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();

サードパーティ エンジンを使用する場合、このコールバックは関連モデルが検索エンジンからすでに取得された後に呼び出されるため、結果の「フィルタリング」には使用しないでください。代わりに Scout where clauses を使用してください。ただし、データベース エンジンを使用する場合、query メソッドの制約はデータベース クエリに直接適用されるため、フィルタリングにも使用できます。

Pagination

モデルのコレクションを取得するだけでなく、paginate メソッドを使用して検索結果をページ分割することもできます。このメソッドは、paginated a traditional Eloquent query がある場合と同様に、Illuminate\Pagination\LengthAwarePaginator インスタンスを返します。

use App\Models\Order;

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

paginate メソッドの最初の引数として量を渡すことで、ページごとに取得するモデルの数を指定できます。

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

データベース エンジンを使用する場合は、simplePaginate メソッドを使用することもできます。ページ番号を表示できるように一致するレコードの総数を取得する paginate とは異なり、simplePaginate は現在のページの先に結果があるかどうかだけを判断するため、「前」と「次」のリンクのみが必要な大規模なデータセットの場合はより効率的になります。

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

結果を取得したら、従来の Eloquent クエリをページ分割した場合と同じように、Blade を使用して結果を表示し、ページ リンクをレンダリングできます。

<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);
});

検索エンジンは Eloquent モデルのグローバル スコープ定義を認識しないため、Scout ページネーションを利用するアプリケーションではグローバル スコープを利用しないでください。または、Scout 経由で検索するときに、グローバル スコープの制約を再作成する必要があります。

Soft Deleting

インデックス付きモデルが soft deleting で、論理的に削除されたモデルを検索する必要がある場合は、config/scout.php 構成ファイルの soft_delete オプションを true に設定します。

'soft_delete' => true,

この構成オプションが true の場合、Scout は検索インデックスから論理的に削除されたモデルを削除しません。代わりに、インデックス付きレコードに非表示の __soft_deleted 属性を設定します。次に、検索時に 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();

論理的に削除されたモデルが forceDelete を使用して完全に削除されると、Scout はそのモデルを検索インデックスから自動的に削除します。

Customizing Engine Searches

エンジンの検索動作の高度なカスタマイズを実行する必要がある場合は、search メソッドの 2 番目の引数としてクロージャーを渡すことができます。たとえば、このコールバックを使用して、検索クエリが 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();

Custom Engines

Writing the Engine

組み込みの Scout 検索エンジンの 1 つがニーズに合わない場合は、独自のカスタム エンジンを作成して Scout に登録できます。エンジンは Laravel\Scout\Engines\Engine 抽象クラスを拡張する必要があります。この抽象クラスには、カスタム エンジンが実装する必要がある 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);

Laravel\Scout\Engines\AlgoliaEngine クラスでのこれらのメソッドの実装を確認すると役立つ場合があります。このクラスは、これらの各メソッドを独自のエンジンに実装する方法を学習するための良い出発点となります。

Registering the Engine

カスタム エンジンを作成したら、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',