Skip to content

全文搜索(FTS5) ​

定义 ​

FTS5(Full-Text Search module 5) 是 SQLite 的全文搜索扩展:以虚表(VIRTUAL TABLE) 形式存储倒排索引,支持对文本列做分词匹配、排序与简单检索语法。适合站内搜索、日志检索、文档标题/正文搜索等场景。

概念要点 ​

  • 虚表:CREATE VIRTUAL TABLE ... USING fts5(...) 创建;底层维护 docid、词项索引,不是普通 B-tree 表。
  • MATCH:在 FTS 表上用 column MATCH 'query' 或 table MATCH 'query' 检索。
  • 分词器(tokenizer):默认按 Unicode 规则分词;可指定 tokenize='porter' 等(入门常用默认即可)。
  • 内容与索引列:可只索引部分列;content= 选项指向外部内容表(contentless / external content 模式)。
  • 排名:bm25() 等辅助函数用于相关性排序(FTS5 内置)。

与 LIKE 对比 ​

方式优点缺点
LIKE '%词%'简单无法分词;前缀 % 难走索引
FTS5 MATCH分词、相关性、短语/前缀需建虚表;中文分词依赖 tokenizer

语法 / 清单表 ​

操作语法
建表CREATE VIRTUAL TABLE name USING fts5(col1, col2, ...)
插入INSERT INTO fts_table VALUES (...) 或 INSERT INTO fts_table(fts_table) VALUES('rebuild')
查询SELECT * FROM fts WHERE col MATCH 'keyword'
短语MATCH '"exact phrase"'
前缀MATCH 'key*'
AND / ORMATCH 'foo AND bar'、MATCH 'foo OR bar'
删除DELETE FROM fts_table WHERE rowid = ?
常用选项tokenize=、content=、content_rowid=、columnsize=

示例 ​

最简 FTS5 表与查询 ​

sql
-- 创建全文索引虚表:title、body 参与搜索
CREATE VIRTUAL TABLE articles_fts USING fts5(
  title,
  body,
  content='articles',      -- 正文存于普通表 articles
  content_rowid='id'       -- 关联 articles.id
);

-- 普通表存完整数据
CREATE TABLE articles (
  id    INTEGER PRIMARY KEY,
  title TEXT NOT NULL,
  body  TEXT NOT NULL
);

-- 插入普通表后,同步 FTS(external content 模式需手动维护或触发器)
INSERT INTO articles (title, body) VALUES ('SQLite 教程', 'FTS5 全文搜索入门');
INSERT INTO articles_fts(rowid, title, body)
  VALUES (last_insert_rowid(), 'SQLite 教程', 'FTS5 全文搜索入门');

-- MATCH 查询:title 或 body 含「搜索」
SELECT a.id, a.title, highlight(articles_fts, 1, '<b>', '</b>') AS snippet
FROM articles_fts
JOIN articles a ON a.id = articles_fts.rowid
WHERE articles_fts MATCH '搜索'
ORDER BY bm25(articles_fts);

独立 FTS 表(无 external content) ​

sql
CREATE VIRTUAL TABLE notes_fts USING fts5(
  title,
  body,
  tokenize='unicode61'   -- 默认类分词;英文可用 porter
);

INSERT INTO notes_fts (title, body)
VALUES ('Meeting', 'discuss roadmap and milestones');

-- 短语 + 前缀
SELECT rowid, title FROM notes_fts
WHERE notes_fts MATCH 'road* AND "mile stones"~1';  -- ~1 为 NEAR 近似(FTS5 语法)

常用选项入门 ​

sql
-- contentless:只存索引不存列值(省空间,查正文需 JOIN 源表)
CREATE VIRTUAL TABLE idx_only USING fts5(
  title,
  content='',
  contentless=1
);

-- 指定不参与索引的 UNINDEXED 列(仅存储不搜索)
CREATE VIRTUAL TABLE docs USING fts5(
  title,
  url UNINDEXED
);

易错点与交叉引用 ​

问题说明
忘记 MATCH对 FTS 表用普通 WHERE col LIKE 不走倒排索引
external content 不同步content= 模式下 INSERT/UPDATE/DELETE 需同步 FTS 或触发器
中文分词默认 tokenizer 对中文按字/规则切分,效果因场景而异;复杂中文需自定义 tokenizer
特殊字符MATCH 字符串中引号、* 等需按 FTS5 语法转义
模块未启用部分环境需编译时启用 FTS5;Cloudflare D1 支持 FTS5(见 D1 差异)

相关章节:SELECT · WHERE 与运算符 · 触发器

SQLite 官方参考 ​