简介
Laravel Scout 是一个基于驱动的简洁方案,用于给 Eloquent 模型添加全文检索能力。它通过模型观察者,自动同步 Eloquent 记录与搜索索引。 Scout 内置了database 引擎,使用 MySQL / PostgreSQL 的全文索引和 LIKE 子句直接搜索数据库,无需外部服务。大规模生产环境中若需要拼写容错、分面搜索、地理搜索,则可以选择外部引擎。
支持的引擎一览
安装
通过 Composer 安装。vendor:publish 命令发布配置文件,会生成 config/scout.php。
Laravel\Scout\Searchable trait。该 trait 会注册模型观察者,实现与搜索驱动的自动同步。
配置队列
使用database 或 collection 之外的引擎时,强烈建议先配置好队列驱动。启动队列 worker 后,索引同步会在后台执行,Web 界面的响应速度将大幅提升。
将 config/scout.php 中的 queue 设为 true。
使用唯一任务
在写入密集的应用中,你可能希望避免同一模型记录的重复索引任务进入队列。在config/scout.php 中注册 MakeSearchableUniquely 和 RemoveFromSearchUniquely 任务类,就能使用唯一化的索引任务。通常在服务提供者的 boot 方法中设置。
各驱动的准备工作
Algolia
使用 Algolia 驱动时,请在config/scout.php 中配置 id 与 secret,并安装 Algolia PHP SDK。
.env 中配置凭证。
索引配置
Algolia 可以通过config/scout.php 管理索引设置。
scout:sync-index-settings 命令,让 Algolia 生效。
Meilisearch
Meilisearch 是一款高性能的开源搜索引擎。本地开发中最简单的方法是使用 Laravel Sail 中的 Docker 服务。.env 中配置驱动与主机。
索引配置(Meilisearch)
在 Meilisearch 中,用于where() 过滤的字段必须提前注册到 filterableAttributes,用于 orderBy() 排序的字段则注册到 sortableAttributes。
>、< 之类的过滤操作。
scout:sync-index-settings。
语义检索与混合检索(Meilisearch)
要在 Meilisearch 中使用语义检索或混合检索,需在索引配置中指定 embedder,并在模型配置中指定嵌入信息。toSearchableEmbedding 方法可返回由 Laravel AI SDK 进行嵌入的源文本,或已预先计算好的嵌入数组。设置完毕后请执行 scout:sync-index-settings。
Typesense
Typesense 是一款高性能的开源搜索引擎,支持关键字、语义、地理及向量检索。.env 中配置连接信息。
toSearchableArray 需要把模型主键 cast 为字符串,把创建时间 cast 为 UNIX 时间戳。
语义检索与混合检索(Typesense)
要在 Typesense 中启用语义检索或混合检索,需要在模型的 Typesense 设置中定义embedding 配置与向量字段。默认情况下,Scout 会使用 Laravel AI SDK 生成嵌入。
toSearchableEmbedding 方法应返回由 Scout 进行嵌入的源文本,或已预先计算好的嵌入数组。
若使用 Typesense 的原生嵌入功能,则无需 Laravel AI SDK 也能生成嵌入。详情请参考 Typesense 官方文档。
Turbopuffer
Turbopuffer 是一款支持全文、语义与混合检索的搜索引擎。要使用 Turbopuffer 驱动,请设置SCOUT_DRIVER 和 API 密钥。
TURBOPUFFER_REGION 可以省略,默认值为 gcp-us-central1。
database / collection 引擎
如果希望在不引入外部服务的情况下添加搜索功能,这两种就是最合适的选项。 database 引擎 使用 MySQL / PostgreSQL 的全文索引和LIKE 子句。多数应用足够使用。
语义检索与混合检索
在启用了pgvector 扩展的 PostgreSQL 上,database 引擎支持语义检索与混合检索。请在模型的数据表中添加可为 null 的向量列和全文索引。由于 Scout 会在模型保存后再存储嵌入,向量列必须允许为 null。
toSearchableEmbedding 方法。该方法可返回由 Scout 进行嵌入的源文本,或已预先计算好的嵌入数组。嵌入默认保存在 embedding 列中,可通过 searchableEmbeddingColumn 方法修改。
collection 引擎 在 PHP 中过滤,因此可在 Laravel 支持的所有数据库(包括 SQLite)上运行。适合本地开发、测试或小数据集。
数据库引擎不像外部引擎那样需要手动管理索引,它直接搜索数据库表。
Turbopuffer 配置
使用 Turbopuffer 时,需要在config/scout.php 的 model-settings 中为每个模型定义可搜索属性和 schema。
searchable-attributes 中的数值是 BM25 的相对权重。在此示例中,标题的匹配对得分的贡献是正文的 3 倍。若要使用语义检索,请添加 embedding 配置和向量的 schema,并让模型的 toSearchableEmbedding 方法返回源文本或嵌入数组。
toSearchableEmbedding。将嵌入的源属性包含在 toSearchableArray 的返回值中,并按如下方式配置。
Searchable trait
自定义 toSearchableArray()
默认情况下,模型的toArray() 全部数据都会写入搜索索引。要自定义同步到索引的数据,可以重写 toSearchableArray 方法。
自定义索引名
默认情况下模型的表名(复数)会被用作索引名。可以通过重写searchableAs 来自定义。
database 引擎的搜索策略
在 database 引擎中,可以通过 PHP Attribute 为每列指定高效的搜索策略。有条件地允许搜索
若只想在特定条件下让模型可被搜索,可以定义shouldBeSearchable 方法。
索引管理
本节命令主要针对 Algolia、Meilisearch、Typesense 等外部引擎。database 引擎无需管理索引。
导入已有记录
在已有项目中引入 Scout 时,可以使用scout:import 命令把已有记录导入索引。
清空索引
要从索引中删除某模型的全部记录,可以使用scout:flush。
暂停索引同步
想在一段 Eloquent 操作期间临时停止与索引的同步,使用withoutSyncingToSearch。
手动添加 / 删除记录
可以基于查询把一批模型加入索引。unsearchable。
delete 时会自动从索引中删除。
搜索
search 方法用来搜索模型。再链上 get 就可以得到 Eloquent 模型集合。
raw 方法。
语义检索
在配置了嵌入的database、Meilisearch、Typesense、Turbopuffer 引擎中,可以基于查询的语义来搜索记录。在搜索查询上链式调用 semantic 方法即可。当由 Scout 生成嵌入时,语义检索与混合检索需要 Laravel AI SDK。如果使用 Typesense 的原生嵌入、Turbopuffer 的原生嵌入或预先计算好的查询向量,则不需要 Laravel AI SDK。
hybrid 方法,并通过参数指定文本检索与语义检索的相对权重。
分页
paginate 方法用来对搜索结果做分页,用法与普通 Eloquent 查询一致。
simplePaginate,因为它不计算总数,对大数据集更高效。
过滤与排序
where 方法可以给搜索查询添加过滤条件。
query 方法用来自定义 Eloquent 查询。
Eager Loading
Scout 会先从搜索引擎获得 ID 列表,再用 Eloquent 取回模型。要避免 N+1 问题,可以在query 方法内使用 with() 提前加载。
makeAllSearchableUsing。
软删除
如果被索引的模型使用了软删除,并希望在搜索时也能搜到已删除的模型,请把config/scout.php 的 soft_delete 设为 true。
withTrashed 或 onlyTrashed 搜索已删除记录。
自定义引擎
若内置引擎不能满足需求,可以自行实现自定义引擎。自定义引擎需继承Laravel\Scout\Engines\Engine 抽象类,并实现下面 8 个方法。
Laravel\Scout\Engines\AlgoliaEngine 类。
创建的自定义引擎需要在 App\Providers\AppServiceProvider 的 boot 方法中注册。
config/scout.php 中作为驱动使用。
相关页面
Eloquent ORM
了解 Eloquent 模型的基础用法。
Eloquent 关联
了解关联定义与 Eager Loading。
队列
Scout 可以配合队列在后台异步同步索引。