イントロダクションIntroduction
ほぼすべてのアプリケーションで検索が必要になります。ユーザーが関連する記事をナレッジベースで検索する場合でも、製品カタログを探索する場合でも、ドキュメントのコーパスに対して自然言語で質問する場合でも、Laravelはこれらの各シナリオを処理するための組み込みツールを提供しており、多くの場合、外部サービスを必要としません。Almost every application needs search. Whether your users are searching a knowledge base for relevant articles, exploring a product catalog, or asking natural-language questions against a corpus of documents, Laravel provides built-in tools to handle each of these scenarios — and you often don't need any external services to get there.
ほとんどのアプリケーションでは、Laravelが提供する組み込みのデータベース駆動型オプションで十分であることがわかります。外部の検索サービスが必要になるのは、タイポ許容、ファセットフィルタリング、または大規模な地理検索などの機能が必要な場合のみです。Most applications will find that the built-in database-powered options provided by Laravel are more than sufficient — external search services are only necessary when you need features like typo tolerance, faceted filtering, or geo-search at massive scale.
全文検索Full-Text Search
キーワードの関連性ランキング(データベースが検索語といかに一致するかに基づいて結果をスコアリングしソートする機能)が必要な場合、LaravelのwhereFullTextクエリビルダメソッドで、MariaDB、MySQL、PostgreSQLのネイティブな全文インデックスを活用できます。全文検索は単語の境界や語幹(ステミング)を理解するため、"running"の検索で"run"を含むレコードに一致させることができます。外部サービスは不要です。When you need keyword relevance ranking — where the database scores and sorts results based on how well they match the search terms — Laravel's whereFullText query builder method leverages native full-text indexes on MariaDB, MySQL, and PostgreSQL. Full-text search understands word boundaries and stemming, so a search for "running" can match records containing "run". No external service is required.
セマンティック/ベクトル検索Semantic / Vector Search
正確なキーワードではなく、意味によって結果を一致させるAI駆動のセマンティック検索の場合、whereVectorSimilarToクエリビルダメソッドが、pgvector拡張機能を使用してPostgreSQLに保存したベクトル埋め込みを使用します。たとえば、「best wineries in Napa Valley(ナパバレーの最高のワイナリー)」を検索すると、単語が重なっていなくても「Top Vineyards to Visit(訪れるべきトップブドウ園)」というタイトルの記事を表示できます。ベクトル検索には、pgvector拡張機能を含むPostgreSQLとLaravel AI SDKが必要です。For AI-powered semantic search that matches results by meaning rather than exact keywords, the whereVectorSimilarTo query builder method uses vector embeddings stored in PostgreSQL with the pgvector extension. For example, a search for "best wineries in Napa Valley" can surface an article titled "Top Vineyards to Visit" — even though the words don't overlap. Vector search requires PostgreSQL with the pgvector extension and the Laravel AI SDK[/docs/{{version}}/ai-sdk].
リランキングReranking
LaravelのAI SDKは、AIモデルを使用して、クエリに対するセマンティックな関連性によって結果セットを並べ替えるリランキング機能を提供します。リランキングは、全文検索のような高速な初期取得ステップの後の第2段階として特に強力であり、スピードとセマンティックな精度の両方を提供します。Laravel's AI SDK[/docs/{{version}}/ai-sdk] provides reranking capabilities that use AI models to reorder any set of results by semantic relevance to a query. Reranking is especially powerful as a second stage after a fast initial retrieval step like full-text search — giving you both speed and semantic accuracy.
Laravel Scout検索Laravel Scout Search
検索インデックスを自動的にEloquentモデルと同期させるSearchableトレイトを必要とするアプリケーションのために、Laravel Scoutは組み込みのデータベースエンジンと、Algolia、Meilisearch、Typesenseなどのサードパーティサービス用のドライバの両方を提供しています。For applications that want a Searchable trait that automatically keeps search indexes in sync with Eloquent models, Laravel Scout[/docs/{{version}}/scout] offers both a built-in database engine and drivers for third-party services like Algolia, Meilisearch, and Typesense.
全文検索Full-Text Search
LIKEクエリは単純な部分一致には適していますが、言語を理解しません。LIKEによる「running」の検索では「run」を含むレコードは見つかりません。また、結果は関連性でランク付けされず、単にデータベースが見つけた順に返されます。全文検索は、単語の境界、語幹、関連性スコアリングを理解する専用のインデックスを使用することで、これら両方の問題を解決し、データベースが最も関連性の高い結果を最初に返せるようにします。While LIKE queries work well for simple substring matching, they don't understand language. A LIKE search for "running" won't find a record containing "run", and results aren't ranked by relevance — they're simply returned in whatever order the database finds them. Full-text search solves both of these problems by using specialized indexes that understand word boundaries, stemming, and relevance scoring, allowing the database to return the most relevant results first.
高速な全文検索はMariaDB、MySQL、PostgreSQLに組み込まれており、外部の検索サービスは不要です。検索したい列に全文インデックスを追加し、それらに対してwhereFullTextクエリビルダメソッドを使用して検索するだけです。Fast full-text search is built into MariaDB, MySQL, and PostgreSQL — no external search service is required. You only need to add a full-text index to the columns you want to search, and then use the whereFullText query builder method to search against them.
Warning! 全文検索は現在、MariaDB、MySQL、PostgreSQLでサポートされています。[!WARNING] Full-text search is currently supported by MariaDB, MySQL, and PostgreSQL.
全文インデックスの追加Adding Full-Text Indexes
全文検索を使用するには、まず検索したい列に全文インデックスを追加します。単一の列にインデックスを追加することも、列の配列を渡して複数のフィールドを一度に検索する複合インデックスを作成することもできます。To use full-text search, first add a full-text index to the columns you want to search. You may add the index to a single column, or pass an array of columns to create a composite index that searches across multiple fields at once:
Schema::create('articles', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('body');
$table->timestamps();
$table->fullText(['title', 'body']);
});
PostgreSQLでは、インデックスに言語設定を指定でき、これにより単語の語幹処理方法を制御できます。On PostgreSQL, you may specify a language configuration for the index, which controls how words are stemmed:
$table->fullText('body')->language('english');
インデックス作成の詳細については、マイグレーションドキュメントを参照してください。For more information on creating indexes, consult the migration documentation[/docs/{{version}}/migrations#available-index-types].
全文クエリの実行Running Full-Text Queries
インデックスを作成したら、whereFullTextクエリビルダメソッドを使用して検索を行います。Laravelはデータベースドライバに応じた適切なSQLを生成します。たとえば、MariaDBとMySQLではMATCH(...) AGAINST(...)、PostgreSQLではto_tsvector(...) @@ plainto_tsquery(...)となります。Once the index is in place, use the whereFullText query builder method to search against it. Laravel will generate the appropriate SQL for your database driver — for example, MATCH(...) AGAINST(...) on MariaDB and MySQL, and to_tsvector(...) @@ plainto_tsquery(...) on PostgreSQL:
$articles = Article::whereFullText('body', 'web developer')->get();
MariaDBとMySQLを使用する場合、結果は自動的に関連性スコア順に並べ替えられます。PostgreSQLでは、whereFullTextは一致するレコードをフィルタリングしますが、関連性によるソートは行いません。PostgreSQLで自動的な関連性ソートが必要な場合は、これを自動で処理するScoutのデータベースエンジンの使用を検討してください。When using MariaDB and MySQL, results are automatically ordered by relevance score. On PostgreSQL, whereFullText filters matching records but does not order them by relevance — if you need automatic relevance ordering on PostgreSQL, consider using Scout's database engine[#database-engine], which handles this for you.
複数の列にまたがる複合全文インデックスを作成した場合は、whereFullTextに同じ列の配列を渡すことで、それらすべてに対して検索できます。If you created a composite full-text index across multiple columns, you may search against all of them by passing the same array of columns to whereFullText:
$articles = Article::whereFullText(
['title', 'body'], 'web developer'
)->get();
orWhereFullTextメソッドを使用して、全文検索句を「or」条件として追加できます。詳細は、クエリビルダドキュメントを参照してください。The orWhereFullText method may be used to add a full-text search clause as an "or" condition. For complete details, consult the query builder documentation[/docs/{{version}}/queries#full-text-where-clauses].
セマンティック/ベクトル検索Semantic / Vector Search
全文検索はキーワードの一致に依存しており、クエリ内の単語がデータ内に(何らかの形で)存在する必要があります。セマンティック検索は根本的に異なるアプローチを取ります。AIが生成したベクトル埋め込みを使用してテキストの「意味」を数値の配列として表現し、その意味がクエリに最も近い結果を見つけます。たとえば、「best wineries in Napa Valley」を検索すると、単語がまったく重なっていなくても「Top Vineyards to Visit」というタイトルの記事を表示できます。Full-text search relies on matching keywords — the words in the query must appear (in some form) in the data. Semantic search takes a fundamentally different approach: it uses AI-generated vector embeddings to represent the meaning of text as arrays of numbers, and then finds results whose meaning is most similar to the query. For example, a search for "best wineries in Napa Valley" can surface an article titled "Top Vineyards to Visit" — even though the words don't overlap at all.
ベクトル検索の基本的なワークフローは、コンテンツの各断片に対してエンベディング(数値配列)を生成してデータと共に保存し、検索時にユーザーのクエリに対してエンベディングを生成し、ベクトル空間でそれに最も近い保存済みエンベディングを見つけることです。The basic workflow for vector search is: generate an embedding (a numeric array) for each piece of content and store it alongside your data, then at search time, generate an embedding for the user's query and find the stored embeddings that are closest to it in vector space.
Note: ベクトル検索には、
pgvector拡張機能を含むPostgreSQLデータベースとLaravel AI SDKが必要です。Laravel Cloud Serverless Postgresデータベース全てには、あらかじめpgvectorを用意済みです。[!NOTE] Vector search requires a PostgreSQL database with thepgvectorextension and the Laravel AI SDK[/docs/{{version}}/ai-sdk]. All Laravel Cloud[https://cloud.laravel.com] Serverless Postgres databases already includepgvector.
エンベディングの生成Generating Embeddings
エンベディングとは、テキストのセマンティックな意味を表す高次元の数値配列(通常は数百または数千の数値)です。LaravelのStringableクラスで利用可能なtoEmbeddingsメソッドを使用して、文字列のエンベディングを生成できます。An embedding is a high-dimensional numeric array (typically hundreds or thousands of numbers) that represents the semantic meaning of a piece of text. You may generate embeddings for a string using the toEmbeddings method available on Laravel's Stringable class:
use Illuminate\Support\Str;
$embedding = Str::of('Napa Valley has great wine.')->toEmbeddings();
複数の入力に対して一度にエンベディングを生成する場合(エンベディングプロバイダへのAPI呼び出しが1回で済むため、1つずつ生成するよりも効率的です)、Embeddingsクラスを使用します。To generate embeddings for multiple inputs at once — which is more efficient than generating them one at a time since it requires only a single API call to the embedding provider — use the Embeddings class:
use Laravel\Ai\Embeddings;
$response = Embeddings::for([
'Napa Valley has great wine.',
'Laravel is a PHP framework.',
])->generate();
$response->embeddings; // [[0.123, 0.456, ...], [0.789, 0.012, ...]]
エンベディングプロバイダの設定、次元のカスタマイズ、およびキャッシュの詳細については、AI SDKドキュメントを参照してください。For more details on configuring embedding providers, customizing dimensions, and caching, consult the AI SDK documentation[/docs/{{version}}/ai-sdk#embeddings].
ベクトルの保存とインデックス作成Storing and Indexing Vectors
ベクトル埋め込みを保存するには、マイグレーションでvector列を定義し、エンベディングプロバイダの出力と一致する次元数を指定します(たとえば、OpenAIのtext-embedding-3-smallモデルの場合は1536)。また、その列でindexを呼び出してHNSW(Hierarchical Navigable Small World)インデックスを作成する必要があります。これにより、大規模なデータセットでの類似性検索が劇的に高速化されます。To store vector embeddings, define a vector column in your migration, specifying the number of dimensions that matches your embedding provider's output (for example, 1536 for OpenAI's text-embedding-3-small model). You should also call index on the column to create an HNSW (Hierarchical Navigable Small World) index, which dramatically speeds up similarity searches on large datasets:
Schema::ensureVectorExtensionExists();
Schema::create('documents', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->vector('embedding', dimensions: 1536)->index();
$table->timestamps();
});
Schema::ensureVectorExtensionExistsメソッドは、テーブルを作成する前にPostgreSQLデータベースでpgvector拡張機能が有効になっていることを確実にします。The Schema::ensureVectorExtensionExists method ensures the pgvector extension is enabled on your PostgreSQL database before creating the table.
Eloquentモデルでは、LaravelがPHP配列とデータベースのベクトル形式の間の変換を自動的に処理するように、ベクトル列をarrayにキャストしてください。On your Eloquent model, cast the vector column to an array so that Laravel automatically handles the conversion between PHP arrays and the database's vector format:
protected function casts(): array
{
return [
'embedding' => 'array',
];
}
ベクトル列とインデックスの詳細については、マイグレーションドキュメントを参照してください。For more details on vector columns and indexes, consult the migration documentation[/docs/{{version}}/migrations#available-column-types].
類似性によるクエリQuerying by Similarity
コンテンツのエンベディングを保存したら、whereVectorSimilarToメソッドを使用して類似したレコードを検索できます。このメソッドは、コサイン類似度を使用して指定したエンベディングと保存済みのベクトルを比較し、minSimilarityしきい値未満の結果をフィルタリングし、最も類似したレコードを先頭にして自動的に結果を関連性順に並べ替えます。しきい値は0.0から1.0の間の値にする必要があり、1.0はベクトルが同一であることを意味します。Once you have stored embeddings for your content, you can search for similar records using the whereVectorSimilarTo method. This method compares the given embedding against the stored vectors using cosine similarity, filters out results below the minSimilarity threshold, and automatically orders the results by relevance — with the most similar records first. The threshold should be a value between 0.0 and 1.0, where 1.0 means the vectors are identical:
$documents = Document::query()
->whereVectorSimilarTo('embedding', $queryEmbedding, minSimilarity: 0.4)
->limit(10)
->get();
便利な機能として、エンベディング配列の代わりに普通の文字列を与えた場合、Laravelは設定されたエンベディングプロバイダを使用して自動的にエンベディングを生成します。つまり、ユーザーが検索クエリを手作業でエンベディングへ変換しなくとも、直接渡すことができます。As a convenience, when a plain string is given instead of an embedding array, Laravel will automatically generate the embedding for you using your configured embedding provider. This means you can pass the user's search query directly without manually converting it to an embedding first:
$documents = Document::query()
->whereVectorSimilarTo('embedding', 'best wineries in Napa Valley')
->limit(10)
->get();
ベクトルクエリをより低レベルで制御するために、whereVectorDistanceLessThan、selectVectorDistance、orderByVectorDistanceメソッドも利用可能です。これらのメソッドを使用すると、類似性スコアではなく距離値を直接操作したり、計算された距離を結果の列として選択したり、順序を手作業で制御したりできます。詳細は、クエリビルダドキュメントおよびAI SDKドキュメントを参照してください。For lower-level control over vector queries, the whereVectorDistanceLessThan, selectVectorDistance, and orderByVectorDistance methods are also available. These methods let you work directly with distance values rather than similarity scores, select the computed distance as a column in your results, or manually control the ordering. For complete details, consult the query builder documentation[/docs/{{version}}/queries#vector-similarity-clauses] and the AI SDK documentation[/docs/{{version}}/ai-sdk#querying-embeddings].
結果のリランキングReranking Results
リランキングとは、AIモデルを使用して、各結果が特定のクエリにいかにセマンティックに関連しているかによって結果セットを並べ替える手法です。エンベディングを事前計算して保存しておく必要があるベクトル検索とは異なり、リランキングは任意のテキストコレクションに対して機能します。生のコンテンツとクエリを入力として受け取り、関連性でソートされたアイテムを返します。Reranking is a technique where an AI model reorders a set of results by how semantically relevant each result is to a given query. Unlike vector search, which requires you to pre-compute and store embeddings, reranking works on any collection of text — it takes the raw content and the query as input and returns the items sorted by relevance.
リランキングは、高速な初期取得ステップの後の第2段階として特に強力です。たとえば、全文検索を使用して数千のレコードから上位50の候補に素早く絞り込み、次にリランキングを使用して最も関連性の高い結果を一番上に配置できます。この「取得してリランキング」パターンは、スピードとセマンティックな精度の両方を提供します。Reranking is especially powerful as a second stage after a fast initial retrieval step. For example, you might use full-text search to quickly narrow thousands of records down to the top 50 candidates, and then use reranking to put the most relevant results at the top. This "retrieve then rerank" pattern gives you both speed and semantic accuracy.
Rerankingクラスを使用して文字列の配列をリランキングします。You may rerank an array of strings using the Reranking class:
use Laravel\Ai\Reranking;
$response = Reranking::of([
'Django is a Python web framework.',
'Laravel is a PHP web application framework.',
'React is a JavaScript library for building user interfaces.',
])->rerank('PHP frameworks');
$response->first()->document; // "Laravel is a PHP web application framework."
Laravelのコレクションには、フィールド名(またはクロージャ)とクエリを受け取るrerankマクロもあり、Eloquentの結果を簡単にリランキングできます。Laravel collections also have a rerank macro that accepts a field name (or closure) and a query, making it easy to rerank Eloquent results:
$articles = Article::all()
->rerank('body', 'Laravel tutorials');
リランキングプロバイダの設定と利用可能なオプションの詳細については、AI SDKドキュメントを参照してください。For complete details on configuring reranking providers and available options, consult the AI SDK documentation[/docs/{{version}}/ai-sdk#reranking].
Laravel ScoutLaravel Scout
上記で説明した検索手法はすべて、コード内で直接呼び出すクエリビルダメソッドです。Laravel Scoutは異なるアプローチを取ります。Eloquentモデルに追加するSearchableトレイトを提供し、Scoutはレコードが作成、更新、削除されるたびに、検索インデックスを自動的に同期させます。これは、インデックスの更新を手作業で管理することなく、モデルを常に検索可能にしておきたい場合に特に便利です。The search techniques described above are all query builder methods that you call directly in your code. Laravel Scout[/docs/{{version}}/scout] takes a different approach: it provides a Searchable trait that you add to your Eloquent models, and Scout automatically keeps your search indexes in sync as records are created, updated, and deleted. This is particularly convenient when you want your models to always be searchable without manually managing index updates.
データベースエンジンDatabase Engine
Scoutの組み込みデータベースエンジンは、既存のデータベースに対して全文検索およびLIKE検索を実行します。外部サービスや追加のインフラは不要です。単にモデルにSearchableトレイトを追加し、検索可能にしたい列を返すtoSearchableArrayメソッドを定義するだけです。Scout's built-in database engine performs full-text and LIKE searches against your existing database — no external service or extra infrastructure required. Simply add the Searchable trait to your model and define a toSearchableArray method that returns the columns you want to be searchable.
PHP属性を使用して、各列の検索戦略を制御できます。SearchUsingFullTextはデータベースの全文インデックスを使用し、SearchUsingPrefixは文字列の先頭からのみ一致させ(example%)、属性のない列は両側にワイルドカードを付けたデフォルトのLIKE戦略(%example%)を使用します。You may use PHP attributes to control the search strategy for each column. SearchUsingFullText will use your database's full-text index, SearchUsingPrefix will only match from the beginning of the string (example%), and any columns without an attribute use a default LIKE strategy with wildcards on both sides (%example%):
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Attributes\SearchUsingFullText;
use Laravel\Scout\Attributes\SearchUsingPrefix;
use Laravel\Scout\Searchable;
class Article extends Model
{
use Searchable;
#[SearchUsingPrefix(['id'])]
#[SearchUsingFullText(['title', 'body'])]
public function toSearchableArray(): array
{
return [
'id' => $this->id,
'title' => $this->title,
'body' => $this->body,
];
}
}
Warning! 列が全文クエリ制約を使用するように指定する前に、その列に全文インデックスが割り当てられていることを確認してください。[!WARNING] Before specifying that a column should use full-text query constraints, ensure that the column has been assigned a full-text index[/docs/{{version}}/migrations#available-index-types].
トレイトを追加したら、Scoutのsearchメソッドを使用してモデルを検索できます。Scoutのデータベースエンジンは、PostgreSQLであっても自動的に結果を関連性順に並べ替えます。Once the trait is added, you may search your model using Scout's search method. Scout's database engine will automatically order results by relevance, even on PostgreSQL:
$articles = Article::search('Laravel')->get();
データベースエンジンは、検索のニーズが中程度で、外部サービスをデプロイせずにScoutの自動インデックス同期の利便性を享受したい場合に最適です。フィルタリング、ペジネーション、ソフトデリート済みレコードの処理など、最も一般的な検索ユースケースをうまく処理します。詳細は、Scoutドキュメントを参照してください。The database engine is a great choice when your search needs are moderate and you want the convenience of Scout's automatic index syncing without deploying an external service. It handles the most common search use cases well, including filtering, pagination, and soft-deleted record handling. For complete details, consult the Scout documentation[/docs/{{version}}/scout#database-engine].
サードパーティエンジンThird-Party Engines
Scoutは、Algolia、Meilisearch、Typesenseなどのサードパーティ検索エンジンもサポートしています。これらの専用検索サービスは、タイポ許容、ファセットフィルタリング、地理検索、カスタムランキングルールなど、非常に大規模なスケールや、高度に洗練した検索体験(search-as-you-type)が必要な場合に重要となる高度な機能を提供します。Scout also supports third-party search engines such as Algolia[https://www.algolia.com/], Meilisearch[https://www.meilisearch.com], and Typesense[https://typesense.org]. These dedicated search services offer advanced features like typo tolerance, faceted filtering, geo-search, and custom ranking rules — features that become important at very large scale or when you need a highly polished search-as-you-type experience.
Scoutはすべてのドライバで統一したAPIを提供しているため、後でデータベースエンジンからサードパーティエンジンに切り替える際も、最小限のコード変更で済みます。まずはデータベースエンジンから始め、アプリケーションのニーズがデータベースの提供能力を超えた場合にのみサードパーティサービスに移行できます。Since Scout provides a unified API across all of its drivers, switching from the database engine to a third-party engine later requires minimal code changes. You may start with the database engine and migrate to a third-party service only if your application's needs outgrow what the database can provide.
サードパーティエンジンの設定に関する詳細は、Scoutドキュメントを参照してください。For complete details on configuring third-party engines, consult the Scout documentation[/docs/{{version}}/scout].
Note: 多くのアプリケーションでは外部検索エンジンは不要です。このページで説明している組み込みの手法で、大部分のユースケースをカバーできます。[!NOTE] Many applications never need an external search engine. The built-in techniques described on this page cover the vast majority of use cases.
テクニックの組み合わせCombining Techniques
このページで説明されている検索手法は互いに排他的なものではなく、それらを組み合わせることでしばしば最良の結果が得られます。ここでは、これらのツールがいかに連携するかを示す2つの一般的なパターンを紹介します。The search techniques described on this page are not mutually exclusive — combining them often produces the best results. Here are two common patterns that demonstrate how these tools work together.
全文取得 + リランキングFull-Text Retrieval + Reranking
全文検索を使用して大規模なデータセットから候補セットを素早く絞り込み、次にリランキングを適用して、それらの候補をセマンティックな関連性でソートします。これにより、データベースネイティブな全文検索のスピードと、AI駆動の関連性スコアリングの精度を両立できます。Use full-text search to quickly narrow a large dataset down to a candidate set, then apply reranking to sort those candidates by semantic relevance. This gives you the speed of database-native full-text search with the accuracy of AI-powered relevance scoring:
$articles = Article::query()
->whereFullText('body', $request->input('query'))
->limit(50)
->get()
->rerank('body', $request->input('query'), limit: 10);
ベクトル検索 + 伝統的なフィルタVector Search + Traditional Filters
ベクトルの類似性と標準的なwhere句を組み合わせて、セマンティック検索をレコードのサブセットに制限します。これは、意味ベースの検索を行いたいが、所有権、カテゴリ、またはその他の属性で結果を制限する必要がある場合に便利です。Combine vector similarity with standard where clauses to scope semantic search to a subset of records. This is useful when you want meaning-based search but need to restrict results by ownership, category, or any other attribute:
$documents = Document::query()
->where('team_id', $user->team_id)
->whereVectorSimilarTo('embedding', $request->input('query'))
->limit(10)
->get();