阅读《Lucene In Action》时,最有帮助的是把“建立索引”和“执行搜索”分开理解。Lucene 是应用内使用的检索库,不是一个自带 HTTP 接口的完整搜索服务器。
文档与字段不是数据库表列的直接替代
Document 表示一条待检索记录,Field 表示其中一个字段。文件可以拆成路径、标题、正文和修改时间,但它们承担的用途不同:有的用于精确定位,有的用于分词检索,有的只需要在结果中展示。
| 需求 | 需要考虑的能力 |
|---|---|
| 根据路径替换已有文件 | 稳定、不分词的标识 |
| 根据正文关键词搜索 | 适合语言的分析器与索引 |
| 返回文件名和摘要 | 存储原始字段或从来源重新读取 |
| 按时间排序 | 对应版本支持的数值和排序结构 |
“存储”决定是否保留可取回的字段内容,“索引”决定能否据此检索;排序还可能需要 DocValues 等独立结构。不能因为字段没有存储,就认为它不能被搜索。
分析过程决定哪些词可以匹配
Analyzer 将文本转换为 token 流,可能包括切词、小写化和停用词处理。索引与查询端必须采用相互匹配的分析规则,否则同一段文字可能根本无法命中。
编码、字段名和业务含义也应一致。日期可以表示为时间戳,但用于范围查询、排序和显示的字段如何组织,要按所用 Lucene 主版本的 API 设计,不能混用书中的 NumericField 与新版 Point 类示例。
写入、可见与持久化
IndexWriter 负责写入和更新,Reader/Searcher 负责读取已有索引视图。写入完成、提交到磁盘、让已有搜索器看到新文档是不同事情,应按近实时读取或重新打开 reader 的流程处理。
索引由多个 segment 组成,合并会影响 IO 与空间。不能把每次写入后强制合并为一个 segment 当作常规优化;先测量查询和写入负载,再决定是否需要专门的离线整理。
从一个最小应用入手,验证稳定 ID 更新、删除、分析器和搜索器刷新,比只背类名更能看清这些机制。桌面搜索器就是将它们串起来的一个例子。
参考:Apache Lucene。