public enum IndexOptions {
// NOTE: order is important here; enum ordinals can be used to compare options.
/** Not indexed */
NONE,
/**
* Only documents are indexed: term frequencies and positions are omitted. Phrase and other
* positional queries on the field will throw an exception, and scoring will behave as if any term
* in the document appears only once.
*/
DOCS,
/**
* Only documents and term frequencies are indexed: positions are omitted. This enables normal
* scoring, except Phrase and other positional queries will throw an exception.
*/
DOCS_AND_FREQS,
/**
* Indexes documents, frequencies and positions. This is a typical default for full-text search:
* full scoring is enabled and positional queries are supported.
*/
DOCS_AND_FREQS_AND_POSITIONS,
/**
* Indexes documents, frequencies, positions and offsets. Character offsets are encoded alongside
* the positions.
*/
DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS,
}
这段代码是 Lucene(一个开源的全文检索引擎库)中定义的一个枚举 `IndexOptions`,用来控制**倒排索引(postings lists)中存储的信息量**。它决定了字段(Field)在索引时记录哪些细节,从而影响索引大小、功能支持和查询能力。
以下是对每个枚举值的**逐条解释**:
1. `NONE`
-
**不建立索引**。
-
字段不会被搜索到,通常用于仅存储但不搜索的字段(如主键、时间戳等)。
2. `DOCS`
-
**只记录文档ID**(即哪些文档包含该词)。
-
**不存储词频(TF)和位置信息**。
-
**后果**:
-
无法使用短语查询(如 `"quick fox"`)。
-
评分时假设每个词在文档中只出现一次(所有词权重相同)。
3. `DOCS_AND_FREQS`
-
**记录文档ID + 词频(TF)**。
-
**不记录位置信息**。
-
**后果**:
-
支持正常评分(如TF-IDF),因为知道词频。
-
仍不支持短语查询(因为不知道词的位置)。
4. `DOCS_AND_FREQS_AND_POSITIONS`
-
**记录文档ID + 词频 + 位置**。
-
**默认的索引选项**,适合大多数全文搜索场景。
-
**支持功能**:
-
正常评分(TF-IDF/BM25)。
-
短语查询(如 `"quick fox"`)。
-
邻近查询(如 `"quick fox"~5`)。
5. `DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS`
-
**记录文档ID + 词频 + 位置 + 字符偏移量(offset)**。
-
**用途**:
-
高亮搜索结果(需要知道词在原文中的起始/结束字符位置)。
-
支持更复杂的文本分析(如提取原始文本片段)。
-
**代价**:索引体积更大。
总结对比表:
| 选项 | 文档ID | 词频(TF) | 位置 | 字符偏移量 | 支持短语查询 | 支持高亮 |
|---------------------------------|--------|----------|------|------------|--------------|----------|
| `NONE` | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| `DOCS` | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| `DOCS_AND_FREQS` | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| `DOCS_AND_FREQS_AND_POSITIONS` | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ |
| `DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
位置是啥信息呢?
使用场景举例:
-
**标题字段**:通常用 `DOCS_AND_FREQS_AND_POSITIONS`(支持搜索和短语查询)。
-
**正文字段**:如果需要高亮,用 `DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS`。
-
**标签字段**:用 `DOCS`(只需知道文档是否包含标签,不关心频率或位置)。
-
**主键ID**:用 `NONE`(仅存储,不搜索)。
"位置"就是**这个词在文档里出现的第几个词**。
举个例子,文档内容是:
> `The quick brown fox jumps over the lazy dog`
-
单词 `"fox"` 出现在第 4 个词的位置,所以它的 **位置值是 3**(Lucene 的位置从 0 开始计数)。
-
如果 `"fox"` 出现两次,比如 `"fox jumps fox"`,那么它的位置信息就是 `[0, 2]`。
有了这个位置信息,Lucene 才能支持:
-
**短语查询**(如 `"quick fox"`):检查 `"quick"` 的位置 + 1 是否等于 `"fox"` 的位置。
-
**邻近查询**(如 `"quick fox"~2`):检查两个词的位置差是否在 2 以内。
如果没有位置信息(如 `DOCS` 或 `DOCS_AND_FREQS`),这些查询就无法实现。
字符偏移(offset)是干嘛的?
字符偏移(**offset**)就是**这个词在原始文本中的起始字符位置和结束字符位置**。
它记录的是**字节或字符级别的"坐标"**,而不是"第几个词"的那种位置。
举个具体例子:
原始文本:
> `The quick fox jumps.`
-
单词 `fox` 的字符偏移是:
-
**起始偏移(start offset)**:10
-
**结束偏移(end offset)**:13
(空格也算字符,`"The quick "` 共 10 个字符,`"fox"` 占 3 个字符)
为什么要记录这个?
主要为了**高亮搜索结果**(highlighting):
- **快速定位原文片段**:
当用户搜索 `"fox"` 时,Lucene 能直接通过偏移量 `[10,13)` 从原文本中截取 `"fox"` 并加粗/标色,而无需重新分词。
- **避免重新分词**:
如果没有偏移量,高亮器需要重新对原文分词,可能因分词器配置差异导致高亮位置错误。
- **支持复杂高亮**:
比如高亮多词组合、跨词组的高亮(如高亮 `"quick fox"` 时,需要知道 `"quick"` 和 `"fox"` 的偏移范围)。
代价是什么?
-
**索引体积更大**:每个词的偏移都要额外存储两个整数(start/end)。
-
**性能略低**:写入和读取时需要额外处理。
何时需要开启?
-
**需要高亮**(如搜索结果高亮、摘要提取)。
-
**需要精确映射回原文片段**(如法律、医疗文本的审计追踪)。
如果不需要高亮,用默认的 `DOCS_AND_FREQS_AND_POSITIONS` 即可,无需记录偏移。