发布于2026-07-06 阅读(0)
扫一扫,手机访问
先从 match() against() 说起。这确实是最稳的起点,不需要一开始就部署 Scout 或 Algolia 这类额外服务。Lara vel 默认没有直接暴露 MySQL 全文索引的支持,但原生 SQL 的能力足够撑起一套可用的方案,而且没有外部依赖,维护成本也低。
很多人踩过的坑,是建表时忘了加 FULLTEXT 索引,或者字段类型不匹配——TEXT 和 VARCHAR 是安全的,但 JSON 字段不行,那是另一个故事了。
DB::statement("ALTER TABLE posts ADD FULLTEXT(title, content)");whereRaw 调用:Post::whereRaw("MATCH(title, content) AGAINST(? IN NATURAL LANGUAGE MODE)", [$keyword])->get();IN NATURAL LANGUAGE MODE 对短词(比如“php”)效果很差,搜不到的话换 IN BOOLEAN MODE,它支持 +、-、* 这类通配操作,灵活得多。
mysql 驱动能省事,但得改默认行为Scout 默认监听 created、updated、deleted 这些事件,但全文检索的常用写法是让你把 title 和 content 合成一个 searchableAs() 字段,否则搜不到。这个设计本身没问题,问题是很多人没重写这个默认行为。
toSearchableArray():return ['title' => $this->title, 'content' => $this->content];php artisan scout:import "App\Models\Post",不跑这一步,新的内容就喂不进去。mysql 驱动本质上还是走 match() against(),只是帮你自动建索引、拼 SQL,适合不想手写 raw 语句的人。queue 的配置,否则搜索结果会出现延迟。MySQL 的全文索引对中文的支持其实非常有限——它按空格和标点切词,中文偏偏没有这种天然分隔。搜“数据库优化”大概率失败,除非你在写入时就手动用空格隔开“数据 库 优 化”。
IN BOOLEAN MODE + 星号通配,比如 "数据库*",但精度低,容易误召回。preg_split('/(? 拆成单字),然后拼成 +"数" +"据" +"库" 这种格式,虽然粗暴,但在小项目中够用。ft_min_word_len 就行”的说法——那是针对英文最小词长的,对中文一点用都没有。whereFullText() 不是 Eloquent 内置方法,别被文档误导网上很多文章提到 Post::whereFullText('title', $q)->get() —— 假的。Eloquent 压根没有这个方法。要么是自定义的 Scope,要么是 Scout 扩展,要么纯粹是抄错代码。
whereFullText,Lara vel 官方也从未提供过这个方法。whereRaw("MATCH(...) AGAINST(...)") 的本地 Scope。protected static function booted() { static::addGlobalScope('fulltext', new FullTextScope()); } 是一种写法。public function scopeWhereFullText($query, $columns, $keyword) { ... },干净、可控。说到底,真正卡住人的从来不是语法,而是 MySQL 全文索引那些隐式的行为:停用词表、最小词长、布尔模式下引号和括号的优先级。调一次 SELECT @@ft_stopword_file, @@ft_min_word_len,比翻三页技术文档都有用。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8