很多 Laravel 项目一开始直接查数据库也能满足需求,但一旦进入模糊检索、数据量变大、搜索响应要更快的场景,单纯依赖数据库往往会吃力。本文不展开比较 Algolia、Sphinx、Solr 等方案,而是基于 Laravel 5.5,按“安装 Scout、接入 Elasticsearch、建立索引、执行搜索”的顺序,把一套可直接上手的接入流程梳理清楚,读者也能据此判断自己的项目需要改哪些配置、看到哪些结果才算接通。
为什么在 Laravel 里用 Scout 接 Elasticsearch
Elasticsearch(下文简称 ES)本身是一个实时的分布式搜索和分析引擎,比较适合承担全文检索、模糊匹配和大批量数据搜索这类任务。
在 Laravel 项目里,Scout 的作用是把“模型如何被索引、如何发起搜索”这层能力统一起来。这样业务代码不需要直接从零拼接搜索引擎调用,而是以 Eloquent 模型为入口,把搜索集成到现有应用结构中。
本文示例基于 laravel5.5,其他版本整体思路差异不大。开始之前,需要先确认机器上已经安装并运行了 Elasticsearch。
安装依赖并完成基础配置
1. 安装 Composer 依赖
先安装 Scout 和 Elasticsearch 驱动包:


composer require laravel/scout
composer require tamayo/laravel-scout-elastic
2. 注册服务提供者
在 config/app.php 的 providers 数组中加入对应的服务提供者:
// config/app.php
'providers' => [
// ...
LaravelScoutScoutServiceProvider::class,
// ...
ScoutEnginesElasticsearchElasticsearchProvider::class,
],
这里的目的很直接:让 Laravel 启动时能加载 Scout,以及 Elasticsearch 对应的引擎扩展。
3. 发布 Scout 配置文件
接着执行下面的命令,生成 Scout 配置:
php artisan vendor:publish --provider="LaravelScoutScoutServiceProvider"
4. 配置 config/scout.php
在 config/scout.php 中补充 Elasticsearch 相关配置:
'elasticsearch' => [
'index' => env('ELASTICSEARCH_INDEX', 'laravel'),
'hosts' => [
env('ELASTICSEARCH_HOST', 'http://localhost:9200'),
],
],
这部分定义了默认索引名和 ES 服务地址,后面会通过环境变量覆盖。
5. 在 .env 中指定驱动与地址
然后打开 .env,加入 Scout 与 Elasticsearch 的运行参数:
# scout配置
SCOUT_DRIVER=elasticsearch
SCOUT_PREFIX=
# elasticsearch 配置
ELASTICSEARCH_INDEX=esdemo
# elasticsearch 地址
ELASTICSEARCH_HOST=http://172.30.6.1:9200
这里最关键的是两项:SCOUT_DRIVER=elasticsearch 表示搜索由 ES 驱动接管;ELASTICSEARCH_HOST 则需要指向实际可访问的 ES 服务地址。
创建模型并建立搜索索引
给模型增加可搜索能力
完成基础配置后,就可以把具体业务模型接入搜索。示例中创建的是 app/Student.php,并通过 Scout 的 Searchable trait 让模型具备索引和搜索能力。
为了便于测试,先准备好数据表和测试数据。数据可以手动执行 SQL 插入,也可以通过 Laravel 的迁移和填充机制生成,重点是让模型对应的数据表里先有可导入的记录。
<?php
namespace App;
use IlluminateDatabaseEloquentModel;
use LaravelScoutSearchable;
/**
* 学生模型
*/
class Student extends Model
{
use Searchable;
/**
* 索引名称
*
* @return string
*/
public function searchableAs()
{
return 'students_index';
}
/**
* 可搜索的数据索引
*
* @return array
*/
public function toSearchableArray()
{
$array = $this->toArray();
// Customize array...
return $array;
}
}
这里有两个值得注意的点:
searchableAs()用来定义索引名称,示例里返回的是students_index。toSearchableArray()决定哪些字段会进入索引。示例里直接返回模型数组,实际项目中通常会按搜索需求裁剪字段。
把已有数据导入索引
模型准备好以后,用 Artisan 命令把现有记录批量导入到搜索索引:
php artisan scout:import "AppStudent"
如果导入过程正常,会看到类似下面这样的输出:
php artisan scout:import "AppStudent"
Imported [AppStudent] models up to ID: 500
Imported [AppStudent] models up to ID: 1000
Imported [AppStudent] models up to ID: 1500
Imported [AppStudent] models up to ID: 2000
Imported [AppStudent] models up to ID: 2500
Imported [AppStudent] models up to ID: 3000
Imported [AppStudent] models up to ID: 3500
Imported [AppStudent] models up to ID: 4000
Imported [AppStudent] models up to ID: 4500
Imported [AppStudent] models up to ID: 5000
Imported [AppStudent] models up to ID: 5500
Imported [AppStudent] models up to ID: 6000
Imported [AppStudent] models up to ID: 6500
Imported [AppStudent] models up to ID: 7000
Imported [AppStudent] models up to ID: 7500
Imported [AppStudent] models up to ID: 8000
Imported [AppStudent] models up to ID: 8500
Imported [AppStudent] models up to ID: 9000
Imported [AppStudent] models up to ID: 9500
Imported [AppStudent] models up to ID: 10000
All [AppStudent] records have been imported.
从这段输出可以看出,Scout 是按批次把模型数据写入 ES,直到全部记录导入完成。只要最后出现 All [AppStudent] records have been imported.,通常就说明这一步已经跑通。
如何验证导入结果并发起搜索
先确认索引中是否已经有数据
导入结束后,可以访问 ES 中对应索引的查询接口,检查刚刚写入的数据是否已经存在。示例中的访问路径是:
如果能查到 students_index 的文档,就说明 Laravel 到 Elasticsearch 的索引链路已经建立完成。这里也能顺手确认两件事:一是 ELASTICSEARCH_INDEX=esdemo 是否生效,二是模型里定义的索引名 students_index 是否正确。
在业务代码里执行搜索
完成索引导入后,搜索调用就可以直接从模型发起:
$studens = AppStudent::search('成燕')->get();
dd($studens);
这一段说明 Scout 接入成功后,开发者面对的仍然是熟悉的模型调用方式:把关键词传给 search(),再通过 get() 取回结果集合。
对于测试场景,可以继续把数据量放大,例如导入几十万甚至上百万条记录,再观察检索性能表现。原文给出的思路也很明确:当搜索需求逐渐从精确查询转向全文检索时,ES 往往会比直接在数据库里硬做搜索更合适。
落地时最值得关注的几个点
如果你按照上面的步骤配置后仍然搜不到结果,通常优先检查下面几项:
- Elasticsearch 服务是否已经正常启动,
ELASTICSEARCH_HOST能否从 Laravel 所在环境访问。 SCOUT_DRIVER是否确实切换为elasticsearch。- 模型是否引入了
Searchabletrait。 searchableAs()返回的索引名,是否和实际检查到的索引一致。- 是否已经执行过
php artisan scout:import "AppStudent",并且导入过程中没有报错。
如果只是想快速判断“有没有接通”,最简单的标准就是三步:配置能加载、导入命令能完成、索引接口能查到数据。只要这三项都成立,后续再去优化字段映射、搜索相关性和索引结构就会顺畅很多。
至于更多高级用法,例如更细的查询能力、索引管理和搜索特性扩展,则可以继续查阅 Elasticsearch 官方文档中的说明。









