根本原因是meilisearch索引名与scout默认约定不一致,scout用类名如app\models\post生成索引名app_models_post,但import可能写入错误索引;需在模型中定义searchableas()指定索引名、flush旧索引并重新import。

为什么搜索返回空结果但没报错?
这是最常遇到的问题:模型已 use Searchable,php artisan scout:import 也跑过了,但 Model::search('xxx')->get() 始终返回空集合。根本原因通常是 Meilisearch 的索引名和 Laravel Scout 默认约定不一致。
- Scout 默认用模型的完整类名(如
App\Models\Post)作为索引名,而 Meilisearch 对索引名里的反斜杠\不友好,会自动转义或截断 - 检查实际创建的索引:用 curl 或 Meilisearch Dashboard 查看
/indexes,大概率看到的是类似app_models_post这样的名称——这是 Scout 自动转换的结果,但 import 时可能写到了别的索引 - 强制指定索引名:在模型里加
public static function searchableAs(): string { return 'posts'; },然后重新运行php artisan scout:import - 别忘了清空旧索引:
php artisan scout:flush App\Models\Post,否则新旧索引混在一起,搜索行为不可预测
中文分词失效、搜“文章”找不到“博客”怎么办?
Meilisearch 默认不带中文分词器,它把“文章”当作一个整体 token,不会拆成“文”“章”,更不会做同义扩展。这不是 Scout 的问题,而是 Meilisearch 本身的语言配置缺失。
- 启动 Meilisearch 时必须显式启用中文支持:
meilisearch --db-path=./data --http-addr=0.0.0.0:7700 --language="zh" - 已有索引需重建:改完配置后,先删掉原索引(Dashboard 或
curl -X DELETE 'http://localhost:7700/indexes/posts'),再重新 import - 如果还想要同义词或拼音搜索,得手动配置
synonyms或借助第三方插件(如meilisearch-chinese-analyzer),Scout 层面不处理这些 - 验证是否生效:用 Dashboard 的
Search标签页直接查“文章”,看返回的hits和explanation字段里是否有分词痕迹
search()->where() 组合查询总超时?
Meilisearch 原生只支持过滤(filter),不支持 SQL 式的 WHERE 条件拼接。Scout 的 where() 方法底层是把条件转成 Meilisearch 的 filter 参数,但写法不对就会触发全量扫描,导致毫秒变秒级。
- 确保被
where()的字段已在 Meilisearch 中设为filterable:运行curl -X PATCH 'http://localhost:7700/indexes/posts/settings' -H 'Content-Type: application/json' --data-binary '{"filterableAttributes": ["status", "user_id"]}' - 布尔值字段要传字符串:
->where('published', 'true'),而不是true;Meilisearch filter 表达式里没有布尔字面量 - 范围查询必须用括号:
->where('created_at', '>=', '2024-01-01')会被 Scout 转成created_at >= 1704067200(时间戳),但前提是created_at在 settings 里设为sortable - 避免链式多个
where():Scout 会拼成单个 filter 字符串,一旦某字段未设为 filterable,整个 filter 失效,退化为全文扫表
本地开发能搜,上线后 502 或连接拒绝?
不是 Scout 配置错了,而是 Meilisearch 服务没暴露或网络策略卡住了。Laravel 默认用 http://127.0.0.1:7700,在 Docker 或云服务器上这地址往往不通。
- 检查
config/scout.php里的meilisearch配置项:'host' => env('MEILISEARCH_HOST', 'http://127.0.0.1:7700'),线上务必改成容器名(如http://meilisearch:7700)或内网 IP - Docker Compose 必须保证 network 互通:Laravel 容器和 Meilisearch 容器要在同一自定义 network 下,不能只靠
links - 云服务器注意安全组:7700 端口对外关闭是常态,但 Laravel 容器访问 Meilisearch 是内网调用,只要两者在同一 VPC 或私有网络即可,别误开公网端口
- 健康检查加一行:
curl -I http://meilisearch:7700/health放进部署脚本,比等 PHP 报错快得多
Meilisearch 的快,建立在配置对、索引清、网络通三个前提上。少一个,Scout 就只能干等超时或者默默返回空——它不会告诉你哪一步断了。











