28 July 2014

阅读《Lucene In Action》时,最有帮助的是把“建立索引”和“执行搜索”分开理解。Lucene 是应用内使用的检索库,不是一个自带 HTTP 接口的完整搜索服务器。

文档与字段不是数据库表列的直接替代

Document 表示一条待检索记录,Field 表示其中一个字段。文件可以拆成路径、标题、正文和修改时间,但它们承担的用途不同:有的用于精确定位,有的用于分词检索,有的只需要在结果中展示。

需求 需要考虑的能力
根据路径替换已有文件 稳定、不分词的标识
根据正文关键词搜索 适合语言的分析器与索引
返回文件名和摘要 存储原始字段或从来源重新读取
按时间排序 对应版本支持的数值和排序结构

“存储”决定是否保留可取回的字段内容,“索引”决定能否据此检索;排序还可能需要 DocValues 等独立结构。不能因为字段没有存储,就认为它不能被搜索。

分析过程决定哪些词可以匹配

Analyzer 将文本转换为 token 流,可能包括切词、小写化和停用词处理。索引与查询端必须采用相互匹配的分析规则,否则同一段文字可能根本无法命中。

编码、字段名和业务含义也应一致。日期可以表示为时间戳,但用于范围查询、排序和显示的字段如何组织,要按所用 Lucene 主版本的 API 设计,不能混用书中的 NumericField 与新版 Point 类示例。

写入、可见与持久化

IndexWriter 负责写入和更新,Reader/Searcher 负责读取已有索引视图。写入完成、提交到磁盘、让已有搜索器看到新文档是不同事情,应按近实时读取或重新打开 reader 的流程处理。

索引由多个 segment 组成,合并会影响 IO 与空间。不能把每次写入后强制合并为一个 segment 当作常规优化;先测量查询和写入负载,再决定是否需要专门的离线整理。

从一个最小应用入手,验证稳定 ID 更新、删除、分析器和搜索器刷新,比只背类名更能看清这些机制。桌面搜索器就是将它们串起来的一个例子。

参考:Apache Lucene。





blog comments powered by Disqus
Fork me on GitHub