ElasticSearch源碼解析(五):排序(評分公式)


ElasticSearch源碼解析(五):排序(評分公式)

轉載自:http://blog.csdn.net/molong1208/article/details/50623948

 

 

一、目的

 

一個搜索引擎使用的時候必定需要排序這個模塊,一般情況下在不選擇按照某一字段排序的情況下,都是按照打分的高低進行一個默認排序的,所以如果正式使用的話,必須對默認排序的打分策略有一個詳細的了解才可以,否則被問起來為什么這個在前面,那個在后面不好辦,因此對Elasticsearch的打分策略詳細的看了下,雖然說還不是了解的很全部,但是大部分都看的差不多了,結合理論以及搜索的結果,做一個簡單的介紹

二、Elasticsearch的打分公式

Elasticsearch的默認打分公式是lucene的打分公式,主要分為兩部分的計算,一部分是計算query部分的得分,另一部分是計算field部分的得分,下面給出ES官網給出的打分公式:

 
  在CODE上查看代碼片派生到我的代碼片
  1. score(q,d)  =    
  2.             queryNorm(q)    
  3.           · coord(q,d)      
  4.           · ∑ (             
  5.                 tf(t in d)     
  6.               · idf(t)²        
  7.               · t.getBoost()   
  8.               · norm(t,d)      
  9.             ) (t in q)      
在此給每一個部分做一個解釋

 

queryNorm(q):

對查詢進行一個歸一化,不影響排序,因為對於同一個查詢這個值是相同的,但是對term於ES來說,必須在分片是1的時候才不影響排序,否則的話,還是會有一些細小的區別,有幾個分片就會有幾個不同的queryNorm值

queryNorm(q)=1 / √sumOfSquaredWeights 

上述公式是ES官網的公式,這是在默認query boost為1,並且在默認term boost為1 的情況下的打分,其中

sumOfSquaredWeights =idf(t1)*idf(t1)+idf(t2)*idf(t2)+...+idf(tn)*idf(tn)

其中n為在query里面切成term的個數,但是上面全部是在默認為1的情況下的計算,實際上的計算公式如下所示:

 

三、實際的打分explain

在實際的時候,例如搜索“無線通信”,如下圖所示,因為一些私人原因,將一些字段打碼,查詢的時候設置explain為true,如下圖所示:



因為使用的是默認的分詞器,所以最后的結果是將“無線通信”分成了四個字,並且認為是四個term來進行計算,最后將計算的結果進行相加得到最后的得分0.7605926,這個分數是“無”的得分+“線”的得分+“通”的得分+“信”的得分,四個term的得分如下圖所示:

最后的得分是0.7605926=0.118954286+0.1808154+0.14515185+0.31567,與上述符合,因為四個詞都出現了所以在這里面的coord=1,總分數的計算知道后,我們單看每一部分的得分的計算,以“無”為例進行介紹:

其中每一個term內部分為兩部分的分數,一部分是queryweight,一部分是fieldweight,其中總分數=queryweight*fieldweight

例如此處queryweight=0.51195854,fieldWeight=0.2323514,所以總的分數就是0.118954286

queryweigth計算:

對於queryweight部分的計算分為兩個部分idf和querynorm,其中idf的值是2.8618271,這個值是如何計算的呢

idf=1+ln(1995/(309+1))=2.8618271,說明在分片四里面共有1995個文檔,召回了包含“無”的309個文檔,因此為這個值

querynorm部分的計算:根據上面“無”“線”“通”“信”四個的分數計算,可以看到,idf的值分別為

無:2.8618271

線:3.1053379

通:2.235371

信:2.901306

所以按照計算公式

  在CODE上查看代碼片派生到我的代碼片
  1. querynorm=1 / √2.8618271*2.8618271+3.1053379*3.1053379+2.235371*2.235371+2.901306*2.901306=0.1788922  

 

所以queryweight部分的值是0.1788922*2.8618271=0.51195854

再次總結下此處的公式:queryweight=idf*queryNorm(d)

fieldweight部分計算:

idf的計算上邊已經算過,在此不詳細敘述

tf的值是在此處出現3次,所以為√3=1.7320508

fieldnorm的值不知道如何計算,按照公式計算不出來explain的值,網上資料說是編解碼導致的,哪位朋友知道如何計算麻煩回復下,多謝

總結下fieldweight部分的計算公式:fieldweight=idf*tf*fieldnorm=1.7320508*2.8618271*0.046875=0.2323514

所以總體的計算就是

  1. score=queryweight*fieldweight=idf*queryNorm(d)*idf*tf*fieldnorm=coord*queryNorm(d)*tf*idf^2*fieldnormview pl


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM