站内搜索怎么做:从 LIKE 到 FTS5
痛点
我的博客一开始用 LIKE '%keyword%' 做搜索。
10 篇博客时:响应 5ms。 1000 篇博客时:响应 800ms。 10w 篇时:超时。
FTS5 是解药
CREATE VIRTUAL TABLE posts_fts USING fts5(
title, content, tags,
content='posts',
content_rowid='id',
tokenize='unicode61'
);unicode61 默认按空格分词,对英文 OK,对中文不行——因为中文没有空格。
中文分词方案
import { Intl } from 'node:experimental'; // 或 nodejieba
function segment(text: string): string {
return new Intl.Segmenter('zh', { granularity: 'word' })
.segment(text)
.map(s => s.segment)
.join(' ');
}
// 写入 FTS 前
const segmented = segment(post.content);
db.prepare(`
INSERT INTO posts_fts (rowid, title, content, tags)
VALUES (?, ?, ?, ?)
`).run(post.id, post.title, segmented, post.tags);触发器自动同步
CREATE TRIGGER posts_ai AFTER INSERT ON posts BEGIN
INSERT INTO posts_fts(rowid, title, content, tags)
VALUES (new.id, new.title, new.content, new.tags);
END;增删改自动同步索引,不用业务代码管。
经验
数据量 < 1k 用 LIKE; 1k-100k 用 FTS5; 100k+ 考虑 Meilisearch / Elasticsearch。 :::