はじめに
アプリケーションに検索機能を追加する方法は用途に応じて複数あります。Laravelはキーワード一致から AI を使ったセマンティック検索まで、外部サービス不要で対応できる組み込みツールを提供しています。機能比較
| 機能 | 外部サービス | 特徴 |
|---|---|---|
whereFullText | 不要 | MariaDB / MySQL / PostgreSQL 組み込みの全文インデックス |
whereVectorSimilarTo | 不要(PostgreSQL + pgvector) | 意味的な類似度で検索。AI SDKが必要 |
Reranking | AI プロバイダー | 任意の結果セットを AI で関連度順に並び替え |
| Laravel Scout | 不要(database エンジン)/ 任意 | Eloquent モデルの自動インデックス同期 |
全文検索
LIKE クエリはシンプルな部分一致には便利ですが、言語を理解しません。全文検索は専用インデックスを使って単語の境界・語形変化・関連度スコアを考慮した検索を行います。
MariaDB・MySQL・PostgreSQL は全文検索を組み込みでサポートしており、外部サービスは不要です。
全文インデックスの追加
全文検索を使うには、まず対象カラムに全文インデックスを追加します。日本語全文検索の注意事項
MySQL での日本語全文検索はやや使いにくい面があります。AWS RDS では N-gram パーサーのみ利用可能で、形態素解析プラグイン(MeCab)を追加できないため制限されます。Laravel Cloud の MySQL も同様と考えられます。PostgreSQL でも日本語の語形変化対応は限定的です。日本語検索の精度が重要な場合は Meilisearch や Typesense などの専用エンジンの利用を検討してください。
MySQL での日本語全文検索はやや使いにくい面があります。AWS RDS では N-gram パーサーのみ利用可能で、形態素解析プラグイン(MeCab)を追加できないため制限されます。Laravel Cloud の MySQL も同様と考えられます。PostgreSQL でも日本語の語形変化対応は限定的です。日本語検索の精度が重要な場合は Meilisearch や Typesense などの専用エンジンの利用を検討してください。
全文クエリの実行
インデックスを追加したらwhereFullText メソッドで検索します。Laravel は使用しているデータベースドライバーに合わせて適切な SQL を生成します(MariaDB / MySQL では MATCH(...) AGAINST(...)、PostgreSQL では to_tsvector(...) @@ plainto_tsquery(...))。
MariaDB・MySQL では結果が自動的に関連度スコア順に並びます。PostgreSQL では
whereFullText はマッチするレコードをフィルタリングするだけで関連度順にはなりません。PostgreSQL で自動的な関連度順が必要な場合は Scout のデータベースエンジン が有効です。orWhereFullText メソッドで OR 条件として全文検索を追加することもできます。詳細はクエリビルダードキュメントを参照してください。
セマンティック / ベクター検索
全文検索はキーワードの一致に依存しています。ベクター検索は根本的に異なるアプローチで、AI が生成したベクター埋め込みを使ってテキストの意味を数値配列として表現し、意味的に近い結果を検索します。 たとえば「best wineries in Napa Valley」という検索で「Top Vineyards to Visit」というタイトルの記事がヒットします。単語は一致しなくても意味が近いからです。ベクター検索には Laravel AI SDK が必要で、PostgreSQL(
pgvector 拡張が必要)と MongoDB(Laravel MongoDB パッケージが必要)をサポートしています。Laravel Cloud のすべての Postgres データベースには pgvector が事前にインストールされています。埋め込みの生成
埋め込みはテキストの意味を表す高次元の数値配列(通常数百〜数千次元)です。Laravel のStringable クラスの toEmbeddings メソッドで生成できます。
Embeddings クラスを使うと効率的です(API 呼び出しが 1 回で済みます)。
ベクターの保存とインデックス作成
ベクター埋め込みを保存するには、マイグレーションでvector カラムを定義します。埋め込みプロバイダーの出力次元数に合わせて dimensions を指定してください(例:OpenAI の text-embedding-3-small は 1536 次元)。index() を呼び出して HNSW インデックスを作成すると、大規模データセットでの類似検索が大幅に高速化されます。
embedding カラムを array にキャストして、PHP 配列とデータベースのベクター形式の変換を自動化します。
類似度による検索
埋め込みを保存したら、whereVectorSimilarTo メソッドで類似レコードを検索できます。コサイン類似度でベクターを比較し、minSimilarity 閾値以下の結果をフィルタリングして、関連性の高い順に自動ソートします。閾値は 0.0〜1.0 の値で、1.0 は完全一致を意味します。
whereVectorDistanceLessThan・selectVectorDistance・orderByVectorDistance も利用できます。詳細はクエリビルダードキュメントと AI SDK ドキュメントを参照してください。
リランキング
リランキングは、AI モデルが結果セットをクエリとの関連度順に並び替える手法です。ベクター検索と異なり、事前に埋め込みを計算・保存する必要はなく、任意のテキストコレクションに適用できます。 全文検索で大量のレコードを素早く絞り込んだ後にリランキングを適用する「検索→リランク」パターンが特に効果的です。データベースの速さと AI の精度を両立できます。rerank マクロがあり、フィールド名(またはクロージャ)とクエリを渡すだけで Eloquent の結果をリランクできます。
Laravel Scout
ここまで説明した検索手法はすべてクエリビルダーのメソッドを直接呼び出すものでした。Laravel Scout は別アプローチを取ります。Eloquent モデルにSearchable トレイトを追加すると、Scout がレコードの作成・更新・削除に合わせて検索インデックスを自動同期します。
データベースエンジン
Scout 組み込みのデータベースエンジンは既存のデータベースに対して全文検索とLIKE 検索を行います。外部サービスもインフラも追加不要です。
toSearchableArray メソッドで検索対象のカラムを定義します。PHP 属性でカラムごとに検索戦略を指定できます。
| 属性 | 検索戦略 |
|---|---|
SearchUsingFullText | 全文インデックスを使用(MATCH...AGAINST / to_tsvector) |
SearchUsingPrefix | 前方一致(example%) |
| なし | 前後ワイルドカード(%example%) |
search メソッドでモデルを検索できます。Scout のデータベースエンジンは PostgreSQL でも自動的に関連度順で結果を返します。
サードパーティエンジン
Scout は Algolia・Meilisearch・Typesense などのサードパーティ検索エンジンもサポートします。これらはタイポ許容・ファセット検索・ジオサーチ・カスタムランキングなど高度な機能を提供します。 Scout は統一 API を提供するため、後でデータベースエンジンからサードパーティエンジンに移行する際のコード変更は最小限で済みます。ほとんどのアプリケーションは外部検索エンジンを必要としません。このページで説明した組み込み手法が大多数のユースケースをカバーします。
技術の組み合わせ
ここまで紹介した検索手法は相互に排他的ではありません。組み合わせることで最良の結果が得られます。全文検索 + リランキング
全文検索で候補を素早く絞り込み、リランキングでセマンティックな関連度順に並び替えます。データベース速度と AI 精度を両立するパターンです。ベクター検索 + 通常のフィルター
ベクター類似検索と通常のwhere 句を組み合わせて、特定のサブセットに絞ったセマンティック検索を実現します。チームやカテゴリーで絞り込みながら意味的な検索をしたい場合に便利です。
関連ページ
Laravel Scout
Searchable トレイトでモデルを自動インデックス同期する完全ガイド。
Laravel AI SDK
ベクター埋め込みとリランキングに必要な AI SDK の設定方法。
クエリビルダー
whereFullText・whereVectorSimilarTo などのクエリビルダーメソッドの詳細。
マイグレーション
全文インデックスとベクターカラムの作成方法。