D1 全文搜索踩坑记
用 SQLite FTS5 给中文博客做搜索,分词是最大的坑。
FTS5 默认的 unicode61 分词器会把一整段连续的中文当成一个词,所以搜“搜索”永远命中不了“全文搜索”。
我的做法
不引入分词库,而是在建索引时把每个汉字拆开,查询时把连续的汉字当成一个短语:
const CJK = /[\u4e00-\u9fff]/gu;
export function tokenize(text: string): string {
return text.toLowerCase().replace(CJK, (c) => ` ${c} `).replace(/\s+/g, ' ').trim();
}
查询“搜索”变成 "搜 索",FTS5 会要求这两个字相邻出现,既不会漏,也不会把“搜…索”分散出现的文章带出来。
还要防什么
用户输入不能直接拼进 MATCH,"、*、NEAR 都是语法。我的办法是先分词,把所有符号丢掉,再给每个词加引号。
| 输入 | 查询 |
|---|---|
| 搜索 | "搜 索" |
| d1 踩坑 | "d1" "踩 坑" |
评论 0