该部分转自: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的分值作为分母,其他文档的分值都除以这个最大值,计算出最终得分。
结果为:
说明,从结果中我们可以看到:
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);运行结果变为:
通过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);运行结果变为: