> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Laravel Scout

> Eloquentモデルに全文検索・セマンティック検索機能を追加する公式パッケージ。Meilisearch・Algolia・Typesense・Turbopuffer・データベースエンジンに対応し、モデルオブザーバーによりインデックスを自動同期します。

## はじめに

**Laravel Scout** は、[Eloquentモデル](/jp/eloquent)に全文検索機能を追加するための、シンプルなドライバーベースのソリューションです。モデルオブザーバーを使用して、Eloquentレコードと検索インデックスを自動的に同期します。

Scout には、MySQL / PostgreSQL の全文インデックスと `LIKE` 句を使ってデータベースを直接検索する組み込みの `database` エンジンが含まれており、外部サービスは不要です。大規模なプロダクション環境で、タイポ許容・ファセット検索・ジオサーチが必要な場合は、外部エンジンが役立ちます。

### 対応エンジン一覧

| エンジン | 特徴 | 用途 |
| - | - | - |
| `database` | MySQL / PostgreSQL の全文インデックス | ほとんどのアプリ |
| `collection` | PHPでフィルタリング（SQLiteも可） | ローカル開発・テスト |
| Meilisearch | オープンソース、タイポ許容、高速 | 本番環境 |
| Algolia | クラウドSaaS、高度な機能 | 本番環境 |
| Typesense | オープンソース、ベクトル検索対応 | 本番環境 |
| Turbopuffer | フルテキスト・セマンティック・ハイブリッド検索 | 本番環境 |

```mermaid theme={null}
flowchart LR
  APP["Laravelアプリ<br>(Eloquentモデル)"] -->|"save / delete"| SCOUT["Laravel Scout<br>(モデルオブザーバー)"]
  SCOUT -->|"インデックス同期"| ENGINE["検索エンジン<br>Meilisearch / Algolia / Typesense / Turbopuffer"]
  USER["ユーザー"] -->|"Model::search()"| APP
  ENGINE -->|"検索結果"| APP
```

## インストール

Composerでパッケージをインストールします。

```shell theme={null}
composer require laravel/scout
```

インストール後、`vendor:publish` コマンドで設定ファイルを公開します。`config/scout.php` が生成されます。

```shell theme={null}
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
```

最後に、検索可能にしたいモデルに `Laravel\Scout\Searchable` トレイトを追加します。このトレイトがモデルオブザーバーを登録し、検索ドライバーとの自動同期を有効にします。

```php theme={null}
<?php

namespace App\Models;

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

class Post extends Model
{
    use Searchable;
}
```

### キューの設定

`database` または `collection` エンジン以外を使用する場合、Scoutを使用する前に[キュードライバー](/jp/queues)の設定を強く推奨します。キューワーカーを動かすことで、インデックス同期操作がバックグラウンドで実行され、Webインターフェースの応答速度が大幅に向上します。

`config/scout.php` の `queue` オプションを `true` に設定します。

```php theme={null}
'queue' => true,
```

接続名とキュー名を指定することもできます。

```php theme={null}
'queue' => [
    'connection' => 'redis',
    'queue' => 'scout'
],
```

設定後、専用のキューワーカーを起動します。

```shell theme={null}
php artisan queue:work redis --queue=scout
```

### ユニークなジョブの使用

書き込みの多いアプリケーションでは、同じモデルレコードに対する重複したキュージョブがキューに登録されるのを防ぎたい場合があります。`config/scout.php` で `MakeSearchableUniquely` と `RemoveFromSearchUniquely` ジョブクラスを登録することで、ユニークなインデックスジョブを使用できます。通常、これはサービスプロバイダーの `boot` メソッドで設定します。

```php theme={null}
use Laravel\Scout\Jobs\MakeSearchableUniquely;
use Laravel\Scout\Jobs\RemoveFromSearchUniquely;
use Laravel\Scout\Scout;

Scout::makeSearchableUsing(MakeSearchableUniquely::class);
Scout::removeFromSearchUsing(RemoveFromSearchUniquely::class);
```

これらのジョブは Laravel の[ユニークなジョブロック](#ユニークなジョブの使用)を使用して、既にキューに登録されている同じモデルレコードの重複したインデックス操作をディスパッチするのを防ぎます。

## ドライバーの前提条件

### Algolia

Algoliaドライバーを使用する場合は、`config/scout.php` に `id` と `secret` の認証情報を設定し、Algolia PHP SDKをインストールします。

```shell theme={null}
composer require algolia/algoliasearch-client-php
```

`.env` ファイルに認証情報を追加します。

```ini theme={null}
ALGOLIA_APP_ID=your-app-id
ALGOLIA_SECRET=your-secret-key
```

#### インデックス設定

Algoliaでは `config/scout.php` でインデックス設定を管理できます。

```php theme={null}
use App\Models\User;

'algolia' => [
    'id' => env('ALGOLIA_APP_ID', ''),
    'secret' => env('ALGOLIA_SECRET', ''),
    'index-settings' => [
        User::class => [
            'searchableAttributes' => ['id', 'name', 'email'],
            'attributesForFaceting' => ['filterOnly(email)'],
        ],
    ],
],
```

設定後、`scout:sync-index-settings` コマンドを実行してAlgoliaに設定を反映させます。

```shell theme={null}
php artisan scout:sync-index-settings
```

### Meilisearch

[Meilisearch](https://www.meilisearch.com) は高速なオープンソース検索エンジンです。ローカル開発では [Laravel Sail](https://laravel.com/docs/sail#meilisearch) のDockerを使うのが最も簡単です。

```shell theme={null}
# Laravel Sailを使う場合
./vendor/bin/sail up -d meilisearch
```

Sailを使わない場合は、Dockerで直接起動できます。

```shell theme={null}
docker run -it --rm \
    -p 7700:7700 \
    getmeili/meilisearch:latest \
    meilisearch --master-key="masterKey"
```

Meilisearch PHP SDKをインストールします。

```shell theme={null}
composer require meilisearch/meilisearch-php http-interop/http-factory-guzzle
```

`.env` ファイルにドライバーとホストを設定します。

```ini theme={null}
SCOUT_DRIVER=meilisearch
MEILISEARCH_HOST=http://127.0.0.1:7700
MEILISEARCH_KEY=masterKey
```

<Warning>
  Scoutをアップグレードする際は、Meilisearchサービス自体の[破壊的変更](https://github.com/meilisearch/Meilisearch/releases)も必ず確認してください。
</Warning>

#### インデックス設定（Meilisearch）

Meilisearchでは `where()` でフィルタリングするカラムを `filterableAttributes` に、`orderBy()` でソートするカラムを `sortableAttributes` に事前登録する必要があります。

```php theme={null}
use App\Models\User;

'meilisearch' => [
    'host' => env('MEILISEARCH_HOST', 'http://localhost:7700'),
    'key' => env('MEILISEARCH_KEY', null),
    'index-settings' => [
        User::class => [
            'filterableAttributes' => ['id', 'name', 'email'],
            'sortableAttributes' => ['created_at'],
        ],
    ],
],
```

数値カラムのデータ型に注意が必要です。Meilisearchは正しい型のデータにのみフィルター操作（`>`、`<` など）を実行できます。

```php theme={null}
public function toSearchableArray(): array
{
    return [
        'id' => (int) $this->id,
        'name' => $this->name,
        'price' => (float) $this->price,
    ];
}
```

設定後、`scout:sync-index-settings` コマンドを実行します。

```shell theme={null}
php artisan scout:sync-index-settings
```

#### セマンティック検索とハイブリッド検索（Meilisearch）

Meilisearchでセマンティック検索またはハイブリッド検索を使うには、インデックス設定でembedderを、モデル設定で埋め込み情報を指定します。

```php theme={null}
'meilisearch' => [
    'index-settings' => [
        Article::class => [
            'embedders' => [
                'default' => [
                    'source' => 'userProvided',
                    'dimensions' => 1536,
                ],
            ],
        ],
    ],
    'model-settings' => [
        Article::class => [
            'embedding' => [
                'embedder' => 'default',
                'dimensions' => 1536,
            ],
        ],
    ],
],
```

モデルの `toSearchableEmbedding` メソッドは、Laravel AI SDKで埋め込む元テキスト、または事前計算済みの埋め込み配列を返します。設定後は `scout:sync-index-settings` を実行してください。

### Typesense

[Typesense](https://typesense.org) は高速なオープンソース検索エンジンで、キーワード検索・セマンティック検索・ジオ検索・ベクトル検索に対応しています。

```shell theme={null}
composer require typesense/typesense-php
```

`.env` ファイルに接続情報を設定します。

```ini theme={null}
SCOUT_DRIVER=typesense
TYPESENSE_API_KEY=masterKey
TYPESENSE_HOST=localhost
TYPESENSE_PORT=8108
TYPESENSE_PATH=
TYPESENSE_PROTOCOL=http
```

Typesenseを使用する場合、`toSearchableArray` メソッドでモデルの主キーを文字列に、作成日時をUNIXタイムスタンプにキャストする必要があります。

```php theme={null}
public function toSearchableArray(): array
{
    return array_merge($this->toArray(), [
        'id' => (string) $this->id,
        'created_at' => $this->created_at->timestamp,
    ]);
}
```

#### セマンティック検索とハイブリッド検索（Typesense）

Typesenseでセマンティック検索・ハイブリッド検索を有効にするには、モデルのTypesense設定で `embedding` 設定とベクターフィールドを定義します。デフォルトではScoutは[Laravel AI SDK](/jp/ai-sdk)を使って埋め込みを生成します。

```php theme={null}
use App\Models\Article;

'model-settings' => [
    Article::class => [
        'collection-schema' => [
            'fields' => [
                ['name' => 'title', 'type' => 'string'],
                ['name' => 'embedding', 'type' => 'float[]', 'num_dim' => 1536],
            ],
        ],
        'search-parameters' => ['query_by' => 'title'],
        'embedding' => [
            'attribute' => 'embedding',
            'dimensions' => 1536,
        ],
    ],
],
```

モデルの `toSearchableEmbedding` メソッドは、Scoutが埋め込む元テキスト、または事前計算済みの埋め込み配列を返します。

```php theme={null}
public function toSearchableEmbedding(): string|array
{
    return $this->title.' '.$this->body;
}
```

<Info>
  Typesenseのネイティブ埋め込み機能を使う場合は、Laravel AI SDKなしでも埋め込みを生成できます。詳細は[Typesense公式ドキュメント](https://typesense.org/docs/latest/api/vector-search.html)を参照してください。
</Info>

### Turbopuffer

[Turbopuffer](https://turbopuffer.com) はフルテキスト・セマンティック・ハイブリッド検索をサポートする検索エンジンです。Turbopufferドライバーを使うには、`SCOUT_DRIVER` とAPIキーを設定します。

```ini theme={null}
SCOUT_DRIVER=turbopuffer
TURBOPUFFER_API_KEY=tpuf_...
TURBOPUFFER_REGION=gcp-us-central1
```

`TURBOPUFFER_REGION` は省略可能で、デフォルトは `gcp-us-central1` です。

### データベース / コレクションエンジン

外部サービスなしで検索を追加したい場合に最適なオプションです。

**データベースエンジン**はMySQL / PostgreSQLの全文インデックスと `LIKE` 句を使用します。ほとんどのアプリケーションでこれで十分です。

```ini theme={null}
SCOUT_DRIVER=database
```

#### セマンティック検索とハイブリッド検索

データベースエンジンは、`pgvector` 拡張を有効にした PostgreSQL でセマンティック検索とハイブリッド検索をサポートします。モデルのテーブルに nullable なベクターカラムと全文インデックスを追加します。Scoutはモデル保存後に埋め込みを保存するため、ベクターカラムは nullable にしてください。

```php theme={null}
Schema::ensureVectorExtensionExists();

Schema::table('articles', function (Blueprint $table) {
    $table->vector('embedding', dimensions: 1536)->nullable();
    $table->vectorIndex('embedding');
    $table->fullText(['title', 'body']);
});
```

モデルに `toSearchableEmbedding` メソッドを定義します。このメソッドはScoutが埋め込む元テキスト、または事前計算済みの埋め込み配列を返します。保存先はデフォルトで `embedding` カラムですが、`searchableEmbeddingColumn` メソッドで変更できます。

**コレクションエンジン**はPHPでフィルタリングするため、SQLiteを含むLaravelがサポートするすべてのデータベースで動作します。ローカル開発・テスト・小規模データセット向けです。

```ini theme={null}
SCOUT_DRIVER=collection
```

<Info>
  データベースエンジンでは、外部エンジンとは異なりインデックスの手動管理は不要です。データベーステーブルを直接検索します。
</Info>

### Turbopufferの設定

Turbopufferでは、モデルごとに検索可能な属性とスキーマを `config/scout.php` の `model-settings` に定義します。

```php theme={null}
'turbopuffer' => [
    'model-settings' => [
        Article::class => [
            'searchable-attributes' => [
                'title' => 3,
                'body' => 1,
            ],
            'schema' => [
                'title' => ['type' => 'string', 'full_text_search' => true],
                'body' => ['type' => 'string', 'full_text_search' => true],
                'status' => ['type' => 'string'],
            ],
        ],
    ],
],
```

`searchable-attributes` の数値はBM25の相対的な重みです。例では、タイトルの一致が本文の3倍のスコアに寄与します。セマンティック検索を使う場合は `embedding` 設定とベクターのスキーマを追加し、モデルの `toSearchableEmbedding` メソッドから元テキストまたは埋め込み配列を返します。

```php theme={null}
'embedding' => [
    'attribute' => 'embedding',
    'dimensions' => 1536,
],

'schema' => [
    'embedding' => ['type' => '[1536]f32', 'ann' => true],
],
```

Turbopufferのネイティブ埋め込みを使う場合は、Laravel AI SDKや `toSearchableEmbedding` は不要です。埋め込みの元属性を `toSearchableArray` の戻り値に含め、次のように設定します。

```php theme={null}
'embedding' => [
    'driver' => 'turbopuffer',
    'attribute' => 'embedding_text',
],
```

## Searchable トレイト

### toSearchableArray() のカスタマイズ

デフォルトでは、モデルの `toArray()` の全データが検索インデックスに保存されます。インデックスに同期するデータをカスタマイズするには、`toSearchableArray` メソッドをオーバーライドします。

```php theme={null}
<?php

namespace App\Models;

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

class Post extends Model
{
    use Searchable;

    /**
     * モデルのインデックス可能なデータ配列を取得します。
     *
     * @return array<string, mixed>
     */
    public function toSearchableArray(): array
    {
        $array = $this->toArray();

        // データをカスタマイズ...

        return $array;
    }
}
```

### インデックス名のカスタマイズ

デフォルトでは、モデルのテーブル名（複数形）がインデックス名として使用されます。`searchableAs` メソッドをオーバーライドしてカスタマイズできます。

```php theme={null}
public function searchableAs(): string
{
    return 'posts_index';
}
```

### データベースエンジン用の検索戦略

データベースエンジンでは、カラムごとに効率的な検索戦略をPHP属性で指定できます。

```php theme={null}
use Laravel\Scout\Attributes\SearchUsingFullText;
use Laravel\Scout\Attributes\SearchUsingPrefix;

#[SearchUsingPrefix(['id', 'email'])]
#[SearchUsingFullText(['bio'])]
public function toSearchableArray(): array
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        'email' => $this->email,
        'bio' => $this->bio,
    ];
}
```

<Warning>
  `SearchUsingFullText` を使用する前に、対象カラムに[全文インデックス](/jp/migrations)が付与されていることを確認してください。
</Warning>

### 条件付きで検索可能にする

特定の条件下でのみモデルを検索可能にしたい場合は、`shouldBeSearchable` メソッドを定義します。

```php theme={null}
/**
 * このモデルを検索可能にすべきか判断します。
 */
public function shouldBeSearchable(): bool
{
    return $this->isPublished();
}
```

<Warning>
  `shouldBeSearchable` はデータベースエンジンでは機能しません。データベースエンジンで同様の動作を実現するには、[where句](#フィルタリングとソート)を使用してください。
</Warning>

## インデックスの管理

<Info>
  このセクションのコマンドは、主にAlgolia・Meilisearch・Typesenseなどのサードパーティエンジンを使用する場合に関係します。データベースエンジンではインデックス管理は不要です。
</Info>

### 既存レコードのインポート

既存プロジェクトにScoutを導入する場合、`scout:import` コマンドで既存レコードをインデックスにインポートします。

```shell theme={null}
php artisan scout:import "App\Models\Post"
```

キューを使ってバックグラウンドでインポートすることもできます。

```shell theme={null}
php artisan scout:queue-import "App\Models\Post" --chunk=500
```

### インデックスのクリア

モデルのすべてのレコードを検索インデックスから削除するには `scout:flush` を使います。

```shell theme={null}
php artisan scout:flush "App\Models\Post"
```

### インデックスの一時停止

Eloquent操作中に検索インデックスとの同期を一時的に止めたい場合は `withoutSyncingToSearch` を使います。

```php theme={null}
use App\Models\Order;

Order::withoutSyncingToSearch(function () {
    // この中のモデル操作は検索インデックスに同期されない
});
```

### レコードの手動追加・削除

クエリを使ってモデルのコレクションをインデックスに追加できます。

```php theme={null}
// クエリ結果を追加
Order::where('price', '>', 100)->searchable();

// リレーション経由で追加
$user->orders()->searchable();
```

インデックスからレコードを削除するには `unsearchable` を使います。

```php theme={null}
Order::where('price', '>', 100)->unsearchable();
```

モデルを `delete` すると、インデックスからも自動的に削除されます。

## 検索

`search` メソッドでモデルを検索します。`get` を連結してEloquentモデルのコレクションを取得します。

```php theme={null}
use App\Models\Order;

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

コントローラーやルートから直接返すとJSONに自動変換されます。

```php theme={null}
use Illuminate\Http\Request;

Route::get('/search', function (Request $request) {
    return Order::search($request->search)->get();
});
```

生の検索結果が必要な場合は `raw` メソッドを使います。

```php theme={null}
$orders = Order::search('Star Trek')->raw();
```

### セマンティック検索

埋め込みを設定した `database`、Meilisearch、Typesense、Turbopuffer エンジンでは、クエリの意味に基づいてレコードを検索できます。検索クエリに `semantic` メソッドを追加します。Scoutが埋め込みを生成する場合、セマンティック検索・ハイブリッド検索には[Laravel AI SDK](/jp/ai-sdk)が必要です。Typesenseのネイティブ埋め込みとTurbopufferのネイティブ埋め込み、事前計算済みのクエリベクターを使う場合はLaravel AI SDKは不要です。

```php theme={null}
$articles = Article::search('電力なしで家を快適に保つ方法')
    ->semantic()
    ->get();
```

対応しているエンジンでは、最小類似度の閾値も指定できます。

```php theme={null}
$articles = Article::search('再生可能エネルギーの蓄電')
    ->semantic(minSimilarity: 0.6)
    ->get();
```

全文検索とセマンティック検索を組み合わせるには `hybrid` メソッドを使います。引数でテキスト検索とセマンティック検索の相対的な重みを指定できます。

```php theme={null}
$articles = Article::search('再生可能エネルギーの蓄電')
    ->hybrid(textWeight: 1, semanticWeight: 2)
    ->get();
```

### ページネーション

`paginate` メソッドで検索結果をページネーションできます。通常のEloquentクエリのページネーションと同様に機能します。

```php theme={null}
$orders = Order::search('Star Trek')->paginate();

// 1ページあたりの件数を指定
$orders = Order::search('Star Trek')->paginate(15);
```

データベースエンジンでは `simplePaginate` も使用できます。総件数を取得しないため大規模データセットで効率的です。

```php theme={null}
$orders = Order::search('Star Trek')->simplePaginate(15);
```

Bladeテンプレートでの表示例：

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

{{ $orders->links() }}
```

## フィルタリングとソート

`where` メソッドで検索クエリにフィルター条件を追加できます。

```php theme={null}
use App\Models\Order;

// 等値フィルター
$orders = Order::search('Star Trek')->where('user_id', 1)->get();

// 配列内のいずれかに一致
$orders = Order::search('Star Trek')->whereIn('status', ['open', 'paid'])->get();

// 配列内のいずれにも一致しない
$orders = Order::search('Star Trek')->whereNotIn('status', ['closed'])->get();
```

<Warning>
  Meilisearchを使用する場合、`where` を使う前に[フィルタリング可能な属性](#インデックス設定（meilisearch）)を設定する必要があります。
</Warning>

`query` メソッドでEloquentクエリをカスタマイズすることもできます。

```php theme={null}
use Illuminate\Database\Eloquent\Builder;

$orders = Order::search('Star Trek')
    ->query(fn (Builder $query) => $query->with('invoices'))
    ->get();
```

## Eager Loading

Scout を使用すると、検索エンジンからIDの一覧を取得した後、Eloquentでモデルを取得します。N+1問題を避けるには、`query` メソッドで `with()` を使ったEager Loadingを指定します。

```php theme={null}
use App\Models\Order;
use Illuminate\Database\Eloquent\Builder;

$orders = Order::search('Star Trek')
    ->query(fn (Builder $query) => $query->with(['invoices', 'user']))
    ->get();
```

バッチインポート時にリレーションをEager Loadするには、`makeAllSearchableUsing` メソッドを定義します。

```php theme={null}
use Illuminate\Database\Eloquent\Builder;

protected function makeAllSearchableUsing(Builder $query): Builder
{
    return $query->with('author');
}
```

<Warning>
  `makeAllSearchableUsing` はキューを使ったバッチインポートでは使用できない場合があります。キュージョブでモデルコレクションが処理されるときにリレーションは復元されません。
</Warning>

## ソフトデリート

インデックスされたモデルが[ソフトデリート](/jp/eloquent)を使用していて、削除済みモデルも検索したい場合は、`config/scout.php` の `soft_delete` オプションを `true` に設定します。

```php theme={null}
'soft_delete' => true,
```

有効にすると、`withTrashed` や `onlyTrashed` で削除済みレコードを検索できます。

```php theme={null}
// 削除済みを含めて検索
$orders = Order::search('Star Trek')->withTrashed()->get();

// 削除済みのみ検索
$orders = Order::search('Star Trek')->onlyTrashed()->get();
```

## カスタムエンジン

組み込みの検索エンジンがニーズに合わない場合は、独自のカスタムエンジンを実装できます。カスタムエンジンは `Laravel\Scout\Engines\Engine` 抽象クラスを継承し、以下の8つのメソッドを実装する必要があります。

```php theme={null}
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` クラスを確認してください。

作成したカスタムエンジンは、`App\Providers\AppServiceProvider` の `boot` メソッドでScoutに登録します。

```php theme={null}
use App\ScoutExtensions\MySqlSearchEngine;
use Laravel\Scout\EngineManager;

public function boot(): void
{
    resolve(EngineManager::class)->extend('mysql', function () {
        return new MySqlSearchEngine;
    });
}
```

登録後、`config/scout.php` でドライバーとして指定します。

```php theme={null}
'driver' => 'mysql',
```

## 関連ページ

<Card title="Eloquent ORM" icon="database" href="/jp/eloquent">
  Eloquentモデルの基本的な使い方を確認します。
</Card>

<Card title="Eloquentリレーション" icon="link" href="/jp/eloquent-relationships">
  リレーションの定義とEager Loadingを確認します。
</Card>

<Card title="キュー" icon="clock" href="/jp/queues">
  Scoutはキューとあわせてインデックスをバックグラウンドで更新できます。
</Card>


## Related topics

- [検索](/jp/search.md)
- [MongoDB](/jp/mongodb.md)
- [Laravel Sail](/jp/sail.md)
- [2026年9月 Laravel アップデート](/jp/blog/changelog/202609.md)
- [2026年8月 Laravel アップデート](/jp/blog/changelog/202608.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.