什么是重叠 token?
重叠 token 是指在分词过程中,同一个文本片段被分词器切分成多个不同的 token,而这些 token 在文本中的位置有交集。换句话说,同一段文本被分词器多次识别为不同的词汇,每个词汇都被当作一个独立的 token。
为什么会出现重叠 token?
重叠 token 的出现主要是因为分词器的 最大正向匹配 策略。这种策略的目标是 尽可能多地匹配出所有可能的词语,以提高召回率。例如,`ik_max_word` 模式会尝试从最长的可能词语开始向下匹配,从而生成多个重叠的 token。
举例说明
假设输入文本是 "中国农业银行",使用 `ik_max_word` 分词器进行分词:
Token 文本 起始字符位置 结束字符位置 位置编号 (pos)
中国农业银行 0 6 1
中国农业 0 4 2
中国 0 2 3
国农 1 3 4
农业银行 2 6 5
农业银 2 5 6
农业 2 4 7
银行 4 6 8
在这个例子中:
- “中国农业银行” 和 “中国农业” 都是从第 0 个字符开始的,因此它们的起始位置重叠。
- “中国农业银行” 和 “中国” 都包含前两个字符 “中国”。
- “农业银行” 和 “农业银行” 的整个文本重叠。
- “农业银” 和 “农业银行” 的前几个字符重叠。
重叠 token 的特点
1. 位置编号不同:
- 每个 token 都有一个独立的位置编号(pos),从 1 开始递增。这些位置编号是 Lucene 在处理查询和位置运算时所依赖的关键信息。
2. 字符范围有交集:
- 这些 token 在原始文本中的字符范围有重叠。例如,“中国农业银行” 和 “中国农业” 都覆盖了文本的前几个字符。
3. 多个 token 表示同一段文本:
- 同一段文本被分词器切成了多个不同的词条,每个词条都被当作一个独立的 token。这些 token 在位置上会有交集,因此被称为“重叠 token”。
重叠 token 的影响
1. 查询时的复杂性:
- 在使用 `SpanNearQuery` 或其他基于位置的查询时,重叠 token 会导致位置计算变得更加复杂。例如,“中国” 和 “农业银行” 的真实位置跨度可能比你预期的要大,因为它们可能不是直接相邻的 token。
2. 索引大小:
- 重叠 token 会增加索引的大小,因为相同的文本片段被存储为多个 token。
如何避免重叠 token?
如果你希望避免重叠 token,可以使用 `ik_smart` 模式。`ik_smart` 模式更倾向于保持术语的完整性,减少重叠 token 的产生。例如,对 "中国农业银行",`ik_smart` 通常会将其切分为一个单独的 token:
```
pos=1: 中国农业银行
```
示例代码
下面是一个简单的示例代码,展示如何使用 `ik_smart` 和 `ik_max_word` 分词器,并打印分词结果:
```java
import org.apache.lucene.analysis.*;
import org.apache.lucene.analysis.ik.IKAnalyzer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
import java.io.S