在本站中
本站是开源的,搜索模块在框架仓库的 crates/modules/search(包名 module-search)。它把博客、五个板块、文档、案例、课程和论坛主题装进一个 tantivy 索引,放在磁盘上的 MmapDirectory 里,启动时打开,之后每 10 分钟增量刷新一次;搜索框的请求经 server function search_query 走到同一个索引。
用到 tantivy 的代码集中在 engine.rs(1063 行,其中后一半是单元测试)和 indexer.rs(777 行)。本站从 0.26.1 升到了 0.27.0(tantivy-jieba 仍是 0.19),这一部分按框架仓库 main 分支当前的代码讲,0.26.1 上的行为只在不同的地方单独说明。
- 本站的搜索模块:schema 七个字段、
jieba_lower分析器、schema 不匹配时清空重建、ReloadPolicy::Manual;每次 upsert 新开一个 50 MB 的 writer,commit_and_reload提交后等后台合并做完再丢掉。早先的写法提交完直接 drop,后台合并全被丢掉:把引擎复制出来按本站的刷新节奏跑一天,只刷新动态来源时段数不涨,每轮夹带一篇改过的文件时 144 轮后 157 个段、删除的旧版本 821 篇,一个案例的 BM25 分数从 39.35 掉到 24.20;等合并之后段数压在 8 以下。jieba 输出的词元一半以上是空白和标点,正文平均长度因此翻倍,命中集合不变、排序会变。查询先截断、转义,不带空格的中文输入变成短语查询。0.26.1 和 0.27.0 的索引格式都是 v7,旧索引直接能开。
flowchart TB
boot["启动"] --> open["open_or_create"]
open --> fresh{"索引为空"}
fresh -- 是 --> full["replace_all"]
fresh -- 否 --> load["直接使用"]
timer["每 600 s"] --> inc["增量刷新"]
inc --> up["upsert_documents"]
inc --> del["delete_documents"]
req["search_query"] --> q["engine.query"]
q --> idx["MmapDirectory 索引"]
full --> idx
up --> idx
del --> idx
各步调到的 tantivy 代码在前几部分讲过:writer 的线程和内存在 IndexWriter,提交在提交,合并和 drop 时丢掉合并在合并,jieba 怎么接进来在分词,删除位图和 fieldnorm 在 fieldnorm 与删除位图。
💬 关联讨论
发起讨论加载中...