【Lucene】SimScorer
SimScorer 就是 Lucene 中真正给“某个 term 在一篇文档里的打分”算分的最小执行单元,被 `TermScorer` 等 scorer 调用,完成 TF-IDF、BM25 等算法的实际数值计算。
---
1. 它在哪?
- 定义在 `org.apache.lucene.search.similarities.Similarity.SimScorer`(内部静态抽象类)。
- 每个 `Similarity` 实现(如 `BM25Similarity`)都会创建自己的 `SimScorer` 子类(如 `BM25Scorer`)。
2. 它做什么?
对外只有两个核心动作:
1. score(float freq, long norm)
根据“词频 freq”和“字段长度编码 norm”立即返回该 term 在该文档的分数。
2. explain(...)
生成人类可读的 `Explanation`,告诉你为啥得这个分。
3. 什么时候被用到?
查询阶段:
- `IndexSearcher` → `TermQuery$TermWeight.scorer()` → `TermScorer` → `TermScorer.score()` 内部调用 `simScorer.score(freq, norm)`。
也就是说,每匹配一篇文档,都会跑一次 `SimScorer.score(...)`。
4. 用 BM25 举例
```java
// 在 BM25Similarity 内部
public final SimScorer simScorer(...) {
...
return new BM25Scorer(boost, k1, b, idf, avgdl, cache);
}
```
`BM25Scorer.score(freq, norm)` 就是标准 BM25 公式:
```java
return weight * (freq / (freq + K(norm)));
```
其中 `K(norm)` 已经预先缓存到 `cache[]` 中,保证每次打分只做一次乘除。
---
✅ 一句话记住
> SimScorer = Lucene 相似度算法的“微积分”:给定词频和文档长度,立刻吐出该 term 的得分。