lucene 的评分机制

该部分转自:http://grantbb.iteye.com/blog/181802 
    通过Searcher.explain(Query query, int doc)方法可以查看某个文档的得分的具体构成。在Lucene中score简单说是由:tf*idf*t*lengthNorm计算得出的。 
      tf :是查询的词在文档中出现的次数的平方根;  idf :表示反转文档频率;  boost :激励因子,可以通过setBoost方法设置,需要说明的通过field和doc都可以设置,所设置的值会同时起作用;  lengthNorm :是由搜索的field的长度决定了,越长文档的分值越低。 
    所以,我们编程能够控制的scroe,就是设置boost的值。 
    为什么一次查询后,最大的分值总是1呢?因为lucene会把计算后,最大分值超过1.0的分值作为分母,其他文档的分值都除以这个最大值,计算出最终得分。 
01 public class ScoreSortTest {
02     public final static String INDEX_STORE_PATH = "index";
03     public static void main(String[] args) throws Exception {
04         IndexWriter writer = new IndexWriter(INDEX_STORE_PATH, new StandardAnalyzer(), true);
05         writer.setUseCompoundFile(false);
06          
07         Document doc1 = new Document();
08         Document doc2 = new Document();
09         Document doc3 = new Document();
10          
11         Field f1 = new Field("bookname","bc bc", Field.Store.YES, Field.Index.TOKENIZED);
12         Field f2 = new Field("bookname","ab bc", Field.Store.YES, Field.Index.TOKENIZED);
13         Field f3 = new Field("bookname","ab bc cd", Field.Store.YES, Field.Index.TOKENIZED);
14          
15         doc1.add(f1);
16         doc2.add(f2);
17         doc3.add(f3);
18          
19         writer.addDocument(doc1);
20         writer.addDocument(doc2);
21         writer.addDocument(doc3);
22          
23         writer.close();
24          
25         IndexSearcher searcher = new IndexSearcher(INDEX_STORE_PATH);
26         TermQuery q = new TermQuery(new Term("bookname""bc"));
27         q.setBoost(2f);
28         Hits hits = searcher.search(q);
29         for(int i=0; i<hits.length();i++){
30             Document doc = hits.doc(i);
31             System.out.print(doc.get("bookname") + "\t\t");
32             System.out.println(hits.score(i));
33             System.out.println(searcher.explain(q, hits.id(i)));//
34         }
35     }
36 }
结果为: 
 
    说明,从结果中我们可以看到: 
      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);运行结果变为: 
 
    发现fieldNorm值有0.625变成了1.25,所以就是乘以了2.0。接下来再对第二个文档增加激励因子:doc2.setBoost(2.0f);运行结果变为: 
 
    发现fieldNorm又乘以了2,所以说对于Document和Field的setBoost都会乘到一起。因为该文档的最终的score超过了1.0变成1.7807949,所以其他的两个文档的最终得分都要除以该值,分别变成: 
bc bc 0.35355335 ab bc cd 0.19999999

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值