本地知识库的全文检索:索引结构、中文分词与结果回跳
本地知识库的全文检索:索引结构、中文分词与结果回跳
做离线典籍类应用时,内容建模往往先被讨论完:目录怎么分层、原文与白话怎么挂接、词条怎么互链。但用户真正高频的动作其实很朴素——只记得半句话,想找回它出现在哪里。这个动作靠目录完不成,得靠一条从关键词到原文位置的完整链路。本文以一款纯本地运行的鸿蒙知识库为例,记录实现侧的几处取舍。
索引该覆盖哪些字段
原文、注解、词条是三类不同来源,如果只建一份扁平索引,结果会按匹配度混在一起,用户还得自己分辨这条命中来自哪里。更合适的做法是在索引条目里保留来源类型,检索时先分组再排序。分组本身几乎不增加计算量,却把「找那句话」和「查相关词条」拆成两条独立路径。
体积也要一起算。索引随内容包落地,词条越长、切分越细,占用越大;把注解这类长文本单独建索引、原文按段落切分,是体积与精度之间比较稳的折中。
中文没有天然边界
英文可以按空格切词,中文不行。典籍类文本句子短、单字信息量大,按单字建索引召回太宽,按整句建又几乎搜不到片段。实践里常用的是二元切分加短语校正:以相邻两字为最小单位建倒排,查询时再把连续的命中合并成片段。这样「只记得两三个字」也能召回,同时不至于把整篇内容都拉出来。
生僻字是另一处坑。要保证输入、索引、显示三层用同一套字符处理,否则会出现「看得见却搜不到」。这件事属于编码与归一化,和排序算法无关,却最容易被漏掉。
结果回跳比命中更影响体验
命中列表只是中间态,真正的终点是原文那一句。索引条目里应当带上段落标识与段内偏移,跳转时才能直接定位到对应位置,而不是停在条目顶部让用户自己往下滚。列表与正文两处都要标出命中的字,否则长段落里还得重新扫一遍。
回退状态同样要留:从正文退回列表时保留关键词与滚动位置,连续核对多处才不用反复输入。没有匹配时给明确提示,别留一片空白。这些边界处理几乎不体现在架构图上,却决定了链路是不是真的闭合。
离线带来的约束
本地检索没有服务端可以兜底,索引必须预构建并随内容包一起分发;内容版本更新时索引要跟着重建,否则会出现命中指向旧段落。把索引版本号和内容版本号绑在一起校验,是避免这类错位最简单的办法。
以上为实现侧的工程记录,具体策略会因语料规模与设备存储而变化。
更多推荐



所有评论(0)