FTS5 全文搜索 (Full-Text Search 5)
FTS5 是 SQLite 内置的全文搜索扩展模块(第 5 代)。它解决的问题是:LIKE '%关键词%' 搜大表要逐行扫全表,越搜越慢;FTS5 预先建好倒排索引 (Inverted Index),搜索时直接查"哪些文档含这个词",复杂度从 O(n) 降到 O(1) 级别的查找。
核心机制:倒排索引
正排是"文档 → 词",倒排是"词 → 文档列表"——就像书的正文和书末索引页的关系:
正文(正排): job_1 = "Python 后端 开发"
job_2 = "Java 后端 开发"
索引(倒排): "Python" → [job_1]
"后端" → [job_1, job_2] ← 查这个词不用扫正文,直接命中代价:索引通常比原文大数倍。zhitu 项目实测:1.08 万条职位,原文(payload 25MB + FTS 存储的内容列 15MB)共约 40MB,FTS5 建出的索引却占约 160MB——中文分词后词项多、文档-词项对(cardinal pairs)多是主因。
基本用法
-- 建虚拟表(不是普通表,是 FTS5 的"虚拟表")
CREATE VIRTUAL TABLE jobs_fts USING fts5(
title, jd_text, content='jobs', content_rowid='id' -- 外部内容表模式,原文不重复存
);
-- 插入后用 MATCH 查询
SELECT rowid FROM jobs_fts WHERE title MATCH '"后端" AND "Python"';
-- 中文需要外置分词器(默认 unicode61 对中文是按"连续汉字串"切,粒度太粗)
-- 常见方案:simple 分词器扩展,或 jieba 预分词后入库要点:
MATCH语法:支持AND / OR / NOT、短语匹配"exact phrase"、前缀prefix*、列限定column:term- 中文分词是 FTS5 在中文场景的头号坑:默认 tokenizer 把整句汉字当一个 token,
MATCH '后端'只能匹配完整连续串。生产可用 wangfenjin/simple 扩展或先用 jieba 切好词再存 content=外部内容模式:原文留在普通表,FTS 只存索引,省一倍空间;代价是外部表变更时要手动INSERT INTO fts(fts, rowid, ...) VALUES('delete', ...)同步- 维护:FTS 索引不自动跟随外部表,删改必须同步重建对应行,否则出现"搜得到但正文已删"的幽灵结果
zhitu 实战:为什么用它、什么场景触发
zhitu(RoleFit)的 job_sqlite.py 里,管理端职位库(1.08 万条职位)建了 job_search_fts 虚拟表,分了 7 个内容列(all_text / jd_text / tag_text / tech_stack_text 等)。
选 FTS5 的理由(相对其他方案):
- 量级匹配:1 万条、单文件 200MB,SQLite 单机绰绰有余,不需要 Elasticsearch(要多跑一个 JVM 服务,3.6G 内存的小服务器养不起)
- 零部署:FTS5 内置于 SQLite,Python 标准库
sqlite3直接可用,和"按需查 SQLite 替代内存常驻"的内存优化方向一致 - 查询场景:管理端的职位筛选/导出接口(
search_jobs_data),用户输入"标题含 xx、公司含 xx"这类关键词过滤——是精确词过滤,不是语义搜索,所以用全文索引,不走向量
触发条件(代码逻辑 job_sqlite.py:707-716):
- 某个文本过滤词
len >= 3时启用 FTS 的MATCH子查询(短词走 LIKE,避免短词倒排命中过多反而慢) - FTS 表存在且至少有一个过滤词 →
s.ordinal + 1 IN (SELECT rowid FROM job_search_fts WHERE {column} MATCH ?) - 否则回退
LIKE '%..%'慢路径
和向量检索的分工(两套互不相干的检索):
| FTS5(关键词) | Qdrant(向量) | |
|---|---|---|
| 查什么 | 职位文本,精确词过滤 | 4867 个标签的 2048 维向量,语义相似召回 |
| 谁在用 | 管理端筛选/导出 | 学生简历 ↔ 职位匹配 |
| 相似性依据 | 字面相同 | 语义相近("前端开发" ≈ "web 工程师") |
相关概念
- 倒排索引(待写)
- SQLite 官方文档:https://www.sqlite.org/fts5.html
本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/Algorithms