Rust in Everything
基于 tantivy 0.27.0

常见坑

每一章对着一个报错或一个现象:先用最小的程序复现,再到源码里找它从哪一行来,最后给出修法和检查办法。前面几部分讲过的机制,这里只链过去。

复现环境都是 M2 Max、macOS 27、rustc 1.99.0、tantivy 0.27.0(默认 feature);和 0.26.x 不同的地方,章里写明。有几个坑是上游的问题,章里写明 tag 之后的 main 上改了没有。

  1. Unsupported dictionary type:某个依赖打开了 quickwit,整个程序换成 sstable 词典;索引能打开,第一次查询才报错。
  2. unsupported variant zstd / unknown compressor id 4:默认构建读 zstd 写的索引;改回 lz4 之后旧段还是 zstd,建 reader 时 panic。
  3. Error getting tokenizer for field:重启后忘了注册分词器;写入到 commit 才报错,之后同一个 writer 不再干活。
  4. 中文字段用 default 分词:搜不到词,长句整句消失:一串汉字是一个词元,40 字节以上的直接丢掉。
  5. 取回来的文档里没有这个字段:没设 STORED,不报错,只是取不到。
  6. delete_term 什么都没删,或者删多了:按 TEXT 字段的原文删除,被分词的字段对不上。
  7. 日期 term 查不到:倒排里只有秒:索引里的日期截到秒,带毫秒的 term 和范围边界都会落空。
  8. Field ts is missing or is not configured as a fast field.:类型读错了,报的却是「字段不存在」。
  9. Failed to acquire Lockfile: LockBusy:同一个索引上第二个 writer,不等待,立刻失败。
  10. The memory arena in bytes per thread needs to be at least 15000000.:预算按线程算;刚过下限的预算写出一堆小段。
  11. 每次提交新开 writer:段只增不减:提交后直接 drop,后台合并被丢掉。
  12. commit 返回了,却搜不到:默认的 reader 每 500 ms 轮询一次 meta.json。
  13. Bus error: 10:映射着的段文件被就地覆盖,进程直接被杀。
  14. 别的用户读不了索引:Permission denied:meta.json 是 0600,reader 还要写锁文件。
  15. The field 'body' does not have positions indexed:自己拼的 TextOptions 默认不记位置,短语查询报错。
  16. 默认 OR 结果太多,AND 又 0 篇:两种默认之间还有「至少命中 k 个词」。
  17. 不带空格的中文查询 0 篇:多词元的一段输入被当成短语;全角空格是语法错误。
  18. grea* 什么都没查到:查询语法里没有单词前缀;短语前缀只展开 50 个词。
  19. graet~1 变成了短语:~ 只是短语的 slop,模糊查询要按字段打开。
  20. Regex queries are not allowed.:0.26.0 起正则默认关闭。
  21. the trait bound TopDocs: Collector is not satisfied:0.26.0 起要写 order_by_score()。
  22. (TopDocs, Count) 一起收,剪枝没了:元组收集器走默认的逐篇收集,单词查询慢 40 倍。
  23. set_multithread_executor 不生效:reader 建好之后再设,已有的 reader 看不见。
  24. Count 能数,TopDocs 报 Field "n" is not indexed.:只设了 FAST 的字段,不打分时才走快速字段。
  25. Field body is not a fast field.:field:* 能解析,搜索时才失败。
  26. 高亮片段只有 50 个汉字:上限按字节算;jieba 搜索模式会让 to_html panic。
  27. terms 聚合的计数和排名不对:每个段只留 size*10 个桶。
  28. 每个带 warmer 的 IndexReader 留下一个线程:gc_loop 不退出,上游问题。

按出在哪里分:

出在哪里坑
feature 与存储格式1 词典类型、2 zstd、13 SIGBUS、14 权限
schema 与分词3 分词器没注册、4 中文 default、5 没 STORED、7 日期精度、8 快速字段类型、15 没有位置
写入与提交6 delete_term、9 LockBusy、10 内存预算、11 drop writer、12 提交后搜不到
查询解析16 OR 与 AND、17 中文短语、18 前缀、19 模糊、20 正则、25 exists
收集器与执行器21 TopDocs、22 元组收集器、23 执行器、24 只有 FAST 的字段
高亮、聚合与 reader26 高亮、27 聚合、28 warmer 线程

本站的搜索模块中过 11(已经改成提交后等合并),17 至今仍是它的行为,见在本站中。

flowchart TB
  q{"碰到了什么"}
  q -->|编译失败| p21["21 TopDocs"]
  q -->|打开或建 reader 时| op{"原文"}
  op -->|"zstd"| p2["2 zstd"]
  op -->|"Permission denied"| p14["14 权限"]
  q -->|写入或提交时报错| wr{"原文"}
  wr -->|"LockBusy"| p9["9 LockBusy"]
  wr -->|"15000000"| p10["10 预算"]
  wr -->|"tokenizer"| p3["3 分词器"]
  q -->|查询时报错| qe{"原文"}
  qe -->|"dictionary type"| p1["1 词典类型"]
  qe -->|"positions"| p15["15 位置"]
  qe -->|"Regex"| p20["20 正则"]
  qe -->|"not indexed"| p24["24 只有 FAST"]
  qe -->|"not a fast field"| p25["25 exists"]
  qe -->|"fast field 类型"| p8["8 快速字段"]
  q -->|进程挂了| crash{"哪种"}
  crash -->|"Bus error"| p13["13 SIGBUS"]
  crash -->|"高亮 panic"| p26["26 高亮"]
  q -->|结果不对| rs{"哪种"}
  rs -->|"中文搜不到"| p417["4 或 17"]
  rs -->|"太多或 0 篇"| p16["16 OR 与 AND"]
  rs -->|"前缀模糊"| p1819["18 或 19"]
  rs -->|"日期"| p7["7 日期"]
  rs -->|"字段是空的"| p5["5 STORED"]
  rs -->|"删除不对"| p6["6 delete_term"]
  rs -->|"刚提交搜不到"| p12["12 可见性"]
  rs -->|"聚合计数"| p27["27 聚合"]
  q -->|越来越慢| sl{"哪种"}
  sl -->|"段越来越多"| p11["11 drop writer"]
  sl -->|"加了 Count"| p22["22 元组"]
  sl -->|"多线程没用"| p23["23 执行器"]
  sl -->|"线程越来越多"| p28["28 warmer"]

💬 关联讨论

发起讨论
加载中...