Skip to content

fix(search): tokenizer 变化时自动重建 FTS 索引#484

Open
Qiyuanqiii wants to merge 1 commit into
TencentCloud:mainfrom
Qiyuanqiii:fix/issue-160-fts-tokenizer-drift
Open

fix(search): tokenizer 变化时自动重建 FTS 索引#484
Qiyuanqiii wants to merge 1 commit into
TencentCloud:mainfrom
Qiyuanqiii:fix/issue-160-fts-tokenizer-drift

Conversation

@Qiyuanqiii

@Qiyuanqiii Qiyuanqiii commented Jul 13, 2026

Copy link
Copy Markdown

关联 Issue

Related to #160

背景与定位

#160 的相关修复目前已经明确分工:

本 PR 不再扩展查询语法净化,而是处理另一条独立的持久化索引一致性问题:运行时 tokenizer 发生变化后,历史 FTS 索引仍保留旧 tokenizer 的写入结构。

问题根因

SQLite FTS5 表会跨进程重启持久化,但当前数据库没有记录索引写入时使用的 tokenizer。

当某次启动无法加载 jieba 时,中文内容会通过 unicode61 fallback 按连续文本写入。后续启动恢复 jieba 后,查询侧会重新按词切分,但既有索引不会重建,因此“北京烤鸭”索引可能无法响应“烤鸭”子词查询。

反向切换同样存在问题:使用 jieba 分词写入的索引,在后续降级为 fallback 查询整句时也可能无法命中。根因不是用户输入语法,而是持久化索引的写入 tokenizer 与当前查询 tokenizer 失配

实现方案

  • 新增 fts_meta 表,持久化 FTS 写入侧 tokenizer 指纹
  • 为两种写入策略定义带版本的稳定指纹:jieba-cut-for-search-v1unicode61-raw-v1
  • 启动时比较已保存指纹与当前运行时 tokenizer
  • 数据库存在 L1/L0 文本且指纹变化时,自动重建两层 FTS 索引
  • 对缺少指纹的既有 v2 数据库执行一次兼容重建
  • 仅在重建流程完成后写入新指纹;流程级失败时保留重试条件
  • 调整重建返回值与日志,明确显示实际使用的 tokenizer

兼容性

当前 tokenizer 与已保存指纹一致时,不会触发额外重建。空数据库只记录当前指纹,不产生无意义的数据扫描。

本 PR 不包含:

  • FTS5 运算符或特殊语法净化
  • tokenizer 输出字符归一化
  • 查询 token 数量限制
  • SQLite/TCVDB 查询接口调整
  • 新的公开配置项或 API
  • 定时、后台或远程索引任务

因此它是持久化 SQLite FTS 索引的启动期自校准,不替代 #178,也不改变正常查询语义。

验证

  • 定向测试:1 个文件、3 项测试通过
  • 完整测试:5 个文件、70 项测试通过
  • 插件及三个脚本构建:通过
  • git diff --check:通过
npm test -- src/core/store/fts-tokenizer-drift.test.ts
npm test
npm run build
git diff --check origin/main...HEAD

定向测试覆盖

  • fallback 写入 L1 后恢复 jieba,验证子词重新可检索
  • jieba 写入 L0 后降级 fallback,验证整句重新可检索
  • 模拟既有 v2 数据库缺少 tokenizer 指纹,验证启动时自动恢复索引
  • 验证重启前确实无法命中、重建后可以命中,避免只测试元数据写入

验证截图

image

@Maxwell-Code07

Copy link
Copy Markdown
Collaborator

hank you for submitting this PR and participating in Tencent Rhino-bird Open-source Training Program!
We have successfully received your submission. The program is currently in full swing, and we will complete the Code Review for you as soon as possible. Please keep an eye on the status notifications for this PR so you can follow up promptly once the review feedback is provided.
Thanks again for your contribution and open-source spirit! 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants