跳转到主要内容

简介

给应用添加搜索功能有多种方式。Laravel 内置了从关键字匹配到基于 AI 的语义检索等一整套工具,很多场景无需引入外部服务。

功能对比

功能外部服务特点
whereFullText不需要MariaDB / MySQL / PostgreSQL 内置的全文索引
whereVectorSimilarTo不需要(PostgreSQL + pgvector)基于语义相似度搜索,需要 AI SDK
RerankingAI 提供商用 AI 对任意结果集按相关度重新排序
Laravel Scout不需要(database 引擎)/ 可选Eloquent 模型自动同步索引

全文检索

LIKE 查询适合简单的模糊匹配,但它并不理解语言。全文检索通过专用索引理解词边界、词形变化和相关度评分。 MariaDB、MySQL、PostgreSQL 都原生支持全文检索,无需外部服务。
全文检索仅支持 MariaDB、MySQL、PostgreSQL。

添加全文索引

要使用全文检索,先在对应列上添加全文索引。
Schema::create('articles', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->text('body');
    $table->timestamps();

    $table->fullText(['title', 'body']); // 联合索引
});
PostgreSQL 允许为索引指定语言,非英语语言下的词形处理会有所不同。
$table->fullText('body')->language('english');
索引相关细节请参考迁移
中文全文检索的注意事项 MySQL 的中文全文检索使用起来较为受限。AWS RDS 上只能使用 N-gram 解析器,不能安装分词插件;Laravel Cloud 上的 MySQL 也是如此。PostgreSQL 对中文分词的支持同样有限。如果你对中文检索精度要求较高,建议考虑 Meilisearch、Typesense 等专用搜索引擎。

执行全文查询

添加索引后,使用 whereFullText 方法进行搜索。Laravel 会根据你使用的数据库驱动生成合适的 SQL(MariaDB / MySQL 生成 MATCH(...) AGAINST(...),PostgreSQL 生成 to_tsvector(...) @@ plainto_tsquery(...))。
$articles = Article::whereFullText('body', 'web developer')->get();
如果创建的是联合索引,就传入相同的列数组。
$articles = Article::whereFullText(
    ['title', 'body'], 'web developer'
)->get();
MariaDB 和 MySQL 会自动按相关度排序返回结果。PostgreSQL 中的 whereFullText 只是过滤匹配的记录,不做相关度排序。如果需要在 PostgreSQL 上自动按相关度排序,可以使用 Scout 的 database 引擎
也可以使用 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 方法生成。
use Illuminate\Support\Str;

$embedding = Str::of('Napa Valley has great wine.')->toEmbeddings();
批量处理多段文本时推荐使用 Embeddings 类,一次 API 调用即可完成。
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 文档

存储向量与创建索引

要保存向量嵌入,需要在迁移中定义 vector 列。请根据所用嵌入提供商的输出维度指定 dimensions(例如 OpenAI 的 text-embedding-3-small 是 1536 维)。调用 index() 创建 HNSW 索引后,大数据集上的相似度检索会显著加速。
Schema::ensureVectorExtensionExists(); // 启用 pgvector 扩展

Schema::create('documents', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->text('content');
    $table->vector('embedding', dimensions: 1536)->index();
    $table->timestamps();
});
在 Eloquent 模型中把 embedding 列 cast 为 array,可以让 PHP 数组与数据库向量格式自动互转。
protected function casts(): array
{
    return [
        'embedding' => 'array',
    ];
}
关于向量列与索引的更多细节请参考迁移

按相似度检索

保存好嵌入后,可以用 whereVectorSimilarTo 方法查询相似记录。它使用余弦相似度比较向量,按 minSimilarity 阈值过滤,并按相关度从高到低自动排序。阈值取 0.01.01.0 表示完全一致。
$documents = Document::query()
    ->whereVectorSimilarTo('embedding', $queryEmbedding, minSimilarity: 0.4)
    ->limit(10)
    ->get();
如果传入的不是嵌入数组而是字符串,Laravel 会自动生成嵌入向量。这样可以直接把用户的搜索关键词传入,非常方便。
$documents = Document::query()
    ->whereVectorSimilarTo('embedding', 'best wineries in Napa Valley')
    ->limit(10)
    ->get();
若需要更细粒度的控制,可以使用 whereVectorDistanceLessThanselectVectorDistanceorderByVectorDistance。详情请参考查询构造器文档AI SDK 文档

重排序(Reranking)

重排序是让 AI 模型按查询相关度对结果集重新排序的技术。与向量检索不同,重排序无需预先计算和存储嵌入,任何文本集合都可以直接使用。 先检索、再重排”是一种非常有效的模式:先用全文检索快速缩小候选,再用 AI 精细排序,可以同时兼顾数据库速度与 AI 精度。
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 Collection 提供了 rerank 宏,只需传入字段名(或闭包)和查询词,就能对 Eloquent 结果重排序。
$articles = Article::all()
    ->rerank('body', 'Laravel tutorials');
关于重排序提供商配置与可用选项,请参考 AI SDK 文档

Laravel Scout

前面介绍的方法都是直接调用查询构造器方法。Laravel Scout 采用不同的思路:给 Eloquent 模型添加 Searchable trait 后,Scout 会随着模型的创建、更新、删除自动同步搜索索引。

database 引擎

Scout 内置的 database 引擎会在你现有的数据库上执行全文搜索与 LIKE 搜索。既不需要外部服务,也不需要额外基础设施。 通过 toSearchableArray 方法定义要参与检索的字段。PHP Attribute 可以为每个字段指定检索策略。
<?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,
        ];
    }
}
Attribute检索策略
SearchUsingFullText使用全文索引(MATCH...AGAINST / to_tsvector
SearchUsingPrefix前缀匹配(example%
前后通配符(%example%
SearchUsingFullText 指定的列必须事先添加全文索引
添加 trait 之后,就可以用 search 方法查询模型。Scout 的 database 引擎在 PostgreSQL 上也会自动按相关度排序返回结果。
$articles = Article::search('Laravel')->get();

第三方引擎

Scout 也支持 AlgoliaMeilisearchTypesense 等第三方搜索引擎,它们提供拼写容错、分面搜索、地理搜索、自定义排序等高级功能。 Scout 提供了统一的 API,因此后续若要从 database 引擎迁移到第三方引擎,代码改动会非常小。
多数应用不需要外部搜索引擎。本页介绍的内置方案已经能覆盖大多数场景。
Scout 详细内容请参考 Laravel Scout 指南

组合使用

上述搜索方式并不互相排斥,组合起来往往效果更佳。

全文检索 + 重排序

先用全文检索快速筛出候选,再用重排序按语义关联度排序。是兼顾数据库速度和 AI 精度的一种模式。
$articles = Article::query()
    ->whereFullText('body', $request->input('query'))
    ->limit(50)
    ->get()
    ->rerank('body', $request->input('query'), limit: 10);

向量检索 + 常规过滤

把向量相似度搜索和普通的 where 子句结合,可以在特定子集内做语义搜索。适合按团队或分类筛选后再进行语义查询的场景。
$documents = Document::query()
    ->where('team_id', $user->team_id)
    ->whereVectorSimilarTo('embedding', $request->input('query'))
    ->limit(10)
    ->get();

相关页面

Laravel Scout

使用 Searchable trait 自动同步模型索引的完整指南。

Laravel AI SDK

向量嵌入与重排序所需的 AI SDK 配置方法。

查询构造器

whereFullText、whereVectorSimilarTo 等查询构造器方法的详细说明。

迁移

全文索引和向量列的创建方法。
最后修改于 2026年7月13日