Laravel 中利用 Scout 集成 Elasticsearch 搜索引擎

温以宁
温以宁
发布时间:2026-08-25 | 63人浏览过
原创

前言

很多 Laravel 项目在搜索量不大时直接查数据库就够用,但一旦进入模糊检索和大数据量场景,性能与体验往往都会掉下来。本文基于 Laravel 5.5,把 Scout 接入 Elasticsearch 的关键步骤按配置、建索引、导入数据和搜索调用四部分梳理出来,方便你快速判断链路是否已经真正跑通。

很多 Laravel 项目一开始直接查数据库也能满足需求,但一旦进入模糊检索、数据量变大、搜索响应要更快的场景,单纯依赖数据库往往会吃力。本文不展开比较 Algolia、Sphinx、Solr 等方案,而是基于 Laravel 5.5,按“安装 Scout、接入 Elasticsearch、建立索引、执行搜索”的顺序,把一套可直接上手的接入流程梳理清楚,读者也能据此判断自己的项目需要改哪些配置、看到哪些结果才算接通。

为什么在 Laravel 里用 Scout 接 Elasticsearch

Elasticsearch(下文简称 ES)本身是一个实时的分布式搜索和分析引擎,比较适合承担全文检索、模糊匹配和大批量数据搜索这类任务。

在 Laravel 项目里,Scout 的作用是把“模型如何被索引、如何发起搜索”这层能力统一起来。这样业务代码不需要直接从零拼接搜索引擎调用,而是以 Eloquent 模型为入口,把搜索集成到现有应用结构中。

本文示例基于 laravel5.5,其他版本整体思路差异不大。开始之前,需要先确认机器上已经安装并运行了 Elasticsearch。

安装依赖并完成基础配置

1. 安装 Composer 依赖

先安装 Scout 和 Elasticsearch 驱动包:

Student 模型建立索引与批量导入的结构示意图
模型到索引的建立过程把模型可搜索化、索引命名和批量导入结果放进同一张结构图里,更容易对照排查。
Laravel Scout 与 Elasticsearch 的接入配置卡片示意图
Scout 接入 ES 的配置关系用编辑卡片梳理依赖安装、服务注册、Scout 配置和 .env 参数之间的对应关系。
composer require laravel/scout
composer require tamayo/laravel-scout-elastic

在 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。
  • 模型是否引入了 Searchable trait。
  • searchableAs() 返回的索引名,是否和实际检查到的索引一致。
  • 是否已经执行过 php artisan scout:import "AppStudent",并且导入过程中没有报错。

如果只是想快速判断“有没有接通”,最简单的标准就是三步:配置能加载、导入命令能完成、索引接口能查到数据。只要这三项都成立,后续再去优化字段映射、搜索相关性和索引结构就会顺畅很多。

至于更多高级用法,例如更细的查询能力、索引管理和搜索特性扩展,则可以继续查阅 Elasticsearch 官方文档中的说明。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表