通过Searcher.explain(Query query, int doc)方法可以查看某个文档的得分的具体构成。
在Lucene中score简单说是由 tf * idf * boost * lengthNorm计算得出的。
tf:是查询的词在文档中出现的次数的平方根
idf:表示反转文档频率,观察了一下所有的文档都一样,所以那就没什么用处,不会起什么决定作用。
boost:激励因子,可以通过setBoost方法设置,需要说明的通过field和doc都可以设置,所设置的值会同时起作用
lengthNorm:是由搜索的field的长度决定了,越长文档的分值越低。
所以我们编程能够控制score的就是设置boost值。
还有个问题,为什么一次查询后最大的分值总是1.0呢?
因为Lucene会把计算后,最大分值超过1.0的分值作为分母,其他的文档的分值都除以这个最大值,计算出最终的得分。
下面用代码和运行结果来进行说明:
public class ScoreSortTest {
public final static String INDEX_STORE_PATH = "index";
public static void main(String[] args) throws Exception {
IndexWriter writer = new IndexWriter(INDEX_STORE_PATH, new StandardAnalyzer(), true);
writer.setUseCompoundFile(false);
Document doc1 = new Document();
Document doc2 = new Document();
Document doc3 = new Document();
Field f1 = new Field("bookname","bc bc", Field.Store.YES, Field.Index.TOKENIZED);
Field f2 = new Field("bookname","ab bc", Field.Store.YES, Field.Index.TOKENIZED);
Field f3 = new Field("bookname","ab bc cd", Field.Store.YES, Field.Index.TOKENIZED);
doc1.add(f1);
doc2.add(f2);
doc3.add(f3);
writer.addDocument(doc1);
writer.addDocument(doc2);
writer.addDocument(doc3);
writer.close();
IndexSearcher searcher = new IndexSearcher(INDEX_STORE_PATH);
TermQuery q = new TermQuery(new Term("bookname", "bc"));
q.setBoost(2f);
Hits hits = searcher.search(q);
for(int i=0; i<hits.length();i++){
Document doc = hits.doc(i);
System.out.print(doc.get("bookname") + "\t\t");
System.out.println(hits.score(i));
System.out.println(searcher.explain(q, hits.id(i)));//
}
}
}
运行结果:
引用
bc bc 0.629606
0.629606 = (MATCH) fieldWeight(bookname:bc in 0), product of:
1.4142135 = tf(termFreq(bookname:bc)=2)
0.71231794 = idf(docFreq=3, numDocs=3)
0.625 = fieldNorm(field=bookname, doc=0)
ab bc 0.4451987
0.4451987 = (MATCH) fieldWeight(bookname:bc in 1), product of:
1.0 = tf(termFreq(bookname:bc)=1)
0.71231794 = idf(docFreq=3, numDocs=3)
0.625 = fieldNorm(field=bookname, doc=1)
ab bc cd 0.35615897
0.35615897 = (MATCH) fieldWeight(bookname:bc in 2), product of:
1.0 = tf(termFreq(bookname:bc)=1)
0.71231794 = idf(docFreq=3, numDocs=3)
0.5 = fieldNorm(field=bookname, doc=2)
从结果中我们可以看到:
bc bc文档中bc出现了2次,tf为2的平方根,所以是1.4142135。而其他的两个文档出现了一次,所以是1.0
所有的三个文档的idf值都是一样的,是0.71231794
默认情况下,boost的值都是1.0,所以lengthNorm就是当前的fieldNorm的值。前两个文档的长度一致,为0.625,而排在最后的文档,因为长度要长一些,所以分值要低,为0.5
现在对f2这个字段增加激励因子:f2.setBoost(2.0f);
运行结果变为:
引用
ab bc 0.8903974
0.8903974 = (MATCH) fieldWeight(bookname:bc in 1), product of:
1.0 = tf(termFreq(bookname:bc)=1)
0.71231794 = idf(docFreq=3, numDocs=3)
1.25 = fieldNorm(field=bookname, doc=1)
发现fieldNorm值有0.625变成了1.25,所以就是乘以了2.0
接下来再对第二个文档增加激励因子:doc2.setBoost(2.0f);
运行结果变为:
引用
ab bc 1.0
1.7807949 = (MATCH) fieldWeight(bookname:bc in 1), product of:
1.0 = tf(termFreq(bookname:bc)=1)
0.71231794 = idf(docFreq=3, numDocs=3)
2.5 = fieldNorm(field=bookname, doc=1)
发现fieldNorm又乘以了2,所以说对于Document和Field的setBoost都会乘到一起。
因为该文档的最终的score超过了1.0变成1.7807949,所以其他的两个文档的最终得分都要除以该值,
分别变成:
引用
bc bc 0.35355335
ab bc cd 0.19999999
相信通过上面的解释,大家就可以形象得理解Lucene的打分机制,同时也知道如何来改变文档的得分。
分享到:
相关推荐
标题与描述均聚焦于“Lucene搜索过程源码解析—Score树”,这表明文章将深入探讨Lucene这一流行的信息检索库在实现搜索功能时的核心机制之一:Score树。Lucene是一个开源的全文检索引擎工具包,它提供了创建索引、...
6. **搜索器(Searcher)**: 搜索器执行查询,根据索引返回匹配的文档,并根据评分(relevancy score)排序。 **Lucene 示例与 Demo** "lucene示例"通常包含了演示如何使用 Lucene 的代码片段或完整的应用。这些...
- **Scoring**: Lucene的评分机制,基于TF-IDF等算法评估文档的相关性。 3. **高级特性**: - **MultiFieldQueryParser**:允许在一个Document的多个Field中进行搜索。 - **Filter**和**QueryWrapperFilter**...
《Lucene 3.0.2:高效Java文件检索库与简单搜索引擎构建指南》 Lucene,这个在Java世界中赫赫有名的全文检索库,以其卓越的性能和易用性,成为了开发人员构建搜索引擎的首选工具。本次我们将深入探讨Lucene 3.0.2...
- **结果排序**:根据文档的评分(Score)对搜索结果进行排序,评分计算涉及到 `Similarity` 类的实现。 - **结果获取**:最后,使用 `Document` 对象从索引中读取搜索结果中的详细信息。 **3. Lucene 源码学习...
- **Score**:Lucene会根据相关性对结果进行评分,高分代表更相关。 - ** Hits**:查询结果集,包括匹配的文档及其分数。 - **Hit**:单个匹配的文档,包括文档ID、分数和其他相关信息。 4. **Compass检索框架**...
7. **Score**:搜索结果的相关性评分,用于排序搜索结果。 【盘古分词知识点】: 1. **中文分词**:由于中文没有明显的词边界,盘古分词是专门针对中文设计的分词工具,能够准确地将连续的汉字序列切分成具有实际...
Lucene 提供了强大的索引和搜索机制,能够对文本进行分词、建立倒排索引,从而实现高效的搜索。倒排索引是一种数据结构,它将每个词汇与包含该词汇的文档列表关联,大大提高了搜索速度。 **2. Lucene 的核心组件** ...
接下来,我们将关注Lucene的排序和评分机制。默认情况下,Lucene根据相关性对搜索结果进行排序,这涉及到TF-IDF算法。我们可能需要定制ScoreFunction或者使用CustomScoreQuery来自定义评分规则,以满足特定业务需求...
7. **搜索相关度评分(Score)**:Lucene为每个匹配查询的文档计算一个分数,表示其与查询的相似度。分数的计算涉及多个因素,包括词频(tf)、逆文档频率(idf)、激励因子(boost)和长度规范(lengthNorm)。高...
Lucene支持两种类型的排序:基于评分(Score Sorting)和基于字段(Field Sorting)。基于评分的排序默认按照相关性排序,即每个文档与查询匹配的程度。而基于字段的排序则可以根据文档的特定字段值进行排序,如日期...
通过阅读和分析这些源码,不仅可以深入理解Lucene的工作机制,还能学习到如何定制Analyzer以适应特定的语言或领域,如何优化索引和查询性能,以及如何利用Lucene进行复杂的信息检索任务。同时,这些源码也能为开发...
4. **评分机制**:Lucene 使用TF-IDF(词频-逆文档频率)算法来计算文档与查询的相关性,得分高的文档优先显示。此外,还可以通过自定义评分函数来优化搜索结果。 5. **更新与删除**:Lucene.NET 2.0 支持对已索引...
- **评分(Score)**: Lucene使用评分机制来决定文档的相关性。评分高的文档被认为更相关。 #### 5. 使用Lucene进行索引和查询 - **索引文档**: 1. 创建`IndexWriter`实例。 2. 使用`addDocument()`方法添加文档。...
Lucene的搜索结果排序基于一个名为评分(Score)的机制。评分是根据查询词在文档中的出现频率、位置等因素计算得出的,高评分意味着文档与查询更匹配。开发者还可以通过定制Similarity类来调整评分算法,以满足特定...
7. **评分(Score)**:Lucene使用TF-IDF算法计算每个匹配文档的相关性分数,得分越高,匹配度越高。 8. **更新与删除(Update & Delete)**:可以通过IndexWriter对索引进行更新,添加新文档或删除旧文档。 9. **分段...
评分(Score):** Lucene使用TF-IDF(Term Frequency-Inverse Document Frequency)算法来计算每个文档的相关性得分。这个得分决定了搜索结果中文档的排序。 #### 三、Lucene与传统数据库系统的比较 **1. 输入输出...
- **Score**: 搜索结果的评分机制,基于TF-IDF等算法,表示文档的相关度。 4. **高亮显示** - Lucene提供Highlighter类,用于在搜索结果中高亮显示匹配的关键词。这有助于用户快速识别搜索结果中与查询相关的部分...
Lucene的默认评分机制基于TF-IDF(词频-逆文档频率),但可以根据实际需求定制。通过实现自己的ScoreFunction,可以调整匹配文档的相关性评分。此外,还可以通过SortField自定义排序规则,比如按照日期、地理位置或...
标题 "lucene-group-score-query" 暗示我们讨论的主题是关于Apache Lucene的一个特定查询功能,即分组评分查询。Lucene是一个流行的全文搜索引擎库,由Java编写,广泛用于构建高效、可扩展的搜索解决方案。这个项目...