solr 使用edismax來控制評分

solr 使用edismax來控制評分

如何控制評分

如果設置了sort字段,那麼將會按照sort字段的順序返回結果。

如果沒有設置sort字段,那麼將會根據相關度打分來排序。也就是說,相關度更高的排在前面。

如何來定製適合自身業務的排序打分規則(boost)呢?經過這段時間的思考與實踐,想到了如下三個方法:
1、定製Lucene的boost算法,加入自己希望的業務規則;
2、使用Solr的edismax實現的方法,通過bf查詢配置來影響boost打分。
3、在建索引的schema時設置一個字段做排序字段,通過它來影響文檔的總體boost打分。

上面每一種方法都有其優劣,下面分析一下各自的優劣。

第一種方法技術難度要求較高,需要讀懂Lucene的boost打分算法,在代碼層做定製.

第二種方式就簡單不少,不過因爲受限於edismax提供的方法,所以有些侷限性。

第三種排序可完全消除文本相關性打分的影響,文本檢索匹配邏輯只負責打到匹配的項,排序由自定義字段處理。

下面重點看edismax的使用:

edismax的理念:

edismax中將查詢字段和查詢詞項分開了,如我們在標準用法中使用name:zjf,那麼在edismax中,需要在qf中設置查詢字段爲name,然後在q中輸入zjf,注意這裏不能加name了,否則沒有結果。

這樣設計的結果就是,查詢詞項會去所有的qf列(query field,可以設置多列,也可以配置爲每列配置權重)上進行查詢,如果要針對每個字段有不同的查詢,如name:zjf,age:30,那麼需要將其中一個移入到fq中,但是注意,fq中的查詢是不影響評分的。這也是edismax的理念。滿足常用的搜索場景。

edismax的常用參數:

q和fq來自標準查詢,也經常使用。

edismax擴展的有:

qf:query field。q中的詞項要在哪些字段上執行查詢。可以設置多列以及每一列的權重。如果沒有設置,那麼將會使用df默認字段(一般在配置文件中配置好)。

pf:parse field。pf和qf的格式一樣。區別是pf會更加註重短語匹配,也就是說如果輸入zjf xhj作爲查詢,那麼在配置了pf的字段上,zjf隨後出現xhj的文檔的評分更高。注意這裏只是評分更高,如果想獲得更加嚴格的短語匹配,應該在查詢中使用"zjf xhj"。

ps:用於配置pf中的詞項的短語間隔。可以控制zjf和xhj之間多少個間隔。

bq:接受一個和q一樣的查詢,它和q的區別是不影響返回的結果集,只會影響排名。

bf:提升函數,通過數學公式來影響評分,而且不侷限在qf中的字段。

mm:最小匹配,如果我們不嚴格要求AND,可以配置mm來定義查詢結果集的匹配程度。

注意:想pf 和qf這種需要查詢的字段上,一定要是indexed的。

關於mm

mm可以設置爲整數,如2,代表至少匹配兩個詞項,如果輸入詞項少於兩個,那麼要全部匹配才行。

mm可以設爲百分比,表示必須匹配到多大的百分比纔可以。也可以合併在一起匹配。

如設置爲mm="2<50%" 那麼如下查詢的話:

solr: 只有一個詞項,必須全部匹配。

solr is:2個詞項,也必須全部匹配。

solr is a:超過兩個,按照50%來計算,只需要匹配一個詞項就可以。(一個詞項佔33%,四捨五入到50%)

solr is a serch:必須匹配兩個,50%。

edismax列子,以下來自網絡

 

例子1,來自網絡。

下面結合最近使用Solr的實踐,着重介紹一下通過使用Solr的DisMaxQParserPlugin通過配置來制定結果文檔打分規則。
DisMaxQParserPlugin提供在針對文本boost打分上,支持搜索多個schema索引字段,並針對每一個字段設置不同的boost權限。
pf查詢 與 qf查詢
pf: 可提供對一條記錄的多個字段做匹配的功能
qf: 針對查詢的每個字段設置不同的boost權重打分,其設置的字段必須爲在pf中配置的項。
可在solrconfig.xml中的browse中配置做如下配置:

<requestHandler name="/browse" class="solr.SearchHandler">
<lst name="defaults">
<str name="defType">edismax</str>
<str name="pf">
name info title
</str>
<str name="qf">
name^1 info^0.8 title^0.6
</str>
</lst>
</requestHandler> 
上面一段的意思是,查詢name,info,title三個字段,每個字段的文本相關度打分分別爲1,0.8,0.6。計算查詢出的每一條結果的權重方法如下:分別計算各字段的文本打分然後乘於配置的系統,最後三者相加即爲該結果的boost得分。

bf查詢
除去pf查詢,qf查詢之外,仍然希望索引記錄的其它字段能夠計入打分中,這時可以使用bf查詢。bf查詢支持一些數據函數,這些函數可作用在索引記錄的字段上,多爲時間,數值等字段。同樣bf也支持添加權重。下面是一個使用bf查詢配置的例子:
<requestHandler name="/browse" class="solr.SearchHandler">
<lst name="defaults">
<str name="defType">edismax</str>
<str name="bf">
sum(recip(ms(NOW,created_time),3.16e-11,1,1),sqrt(log(max(sales,1))),sqrt(log(count)))^10
</str>
<str name="pf">
name info title
</str>
<str name="qf">
name^1 info^0.8 title^0.6
</str>
</lst>
</requestHandler>
其中sum,recip,ms,sqrt,log,max這些都是Solr提供的數學方法,支持的所有數學方法可在這裏查找到:http://wiki.apache.org/solr/FunctionQuery
edismax相關資源:http://wiki.apache.org/solr/DisMaxQParserPlugin

 

 

sum

 

 Solr1.3 sum(x,y,...) 返回多個函數的和。

 

recip

 

recip(x,m,a,b)實現a/(m * x + b)的互逆函數。 m,a,b是常數,x是任何數字字段或任意複雜的函數。

當a和b相等,x> = 0時,該函數的最大值爲1,隨x增加而下降。 將a和b的值增加在一起導致整個功能的移動到曲線的較平坦部分。 這些屬性可以使這成爲在x是rord(datefield)時提升更新文檔的理想功能。

 

max

 

max(x,c) returns the max of another function and a constant. Useful for "bottoming out" another function at some constant.

 

 

log

 

 Solr1.3 log(x) returns log base 10 of the function x. 返回函數x的log10。

 

sqrt

 

 Solr1.3 sqrt(x) returns the square root of the function x返回函數x的平方根

 

例子2,來自http://www.xuebuyuan.com/323380.html

舉一個例子,電商類網站(比如淘寶)的商品搜索:

1.在商品名稱上出現搜索關鍵字排序靠前,而內容的次之

2.對多皇冠的買家排序靠前等

3.對近期發佈的商品排序靠前

4.對最近銷售多商品靠前

綜上獲得一個綜合排名

在solrconfig.xml的SearchHandler中如下配置

 Xml代碼  

  1. <requestHandler name="standard" class="solr.StandardRequestHandler" default="true" >  
  2.     <lst name="defaults">  
  3.         <str name="echoParams">explicit</str>  
  4.         <str name="rows">10</str>  
  5.         <str name="hl">on</str>  
  6.         <str name="hl.fl">name,content</str>  
  7.         <str name="f.content.hl.fragsize">200</str>  
  8.         <str name="defType">edismax</str>  
  9.         <str name="bf">  
  10.             sum(recip(ms(NOW,pub_date),1,1,100),div(point,5632000),div(sale_count,1000000))  
  11.         </str>         
  12.         <str name="pf">  
  13.             content  
  14.         </str>         
  15.         <str name="qf">  
  16.             name^1.9   
  17.         </str>  
  18.     </lst>  
  19. </requestHandler>  

 

div

 

 Solr1.3 div(x,y) divides the function x by the function y.

 

 ms

 

 Solr1.4

Returns milliseconds of difference between it's arguments.

Dates are relative to the Unix or POSIX time epoch, midnight, January 1, 1970 UTC.

Arguments may be numerically indexed date fields such as TrieDate (recommended field type for dates since Solr 1.4), or date math (examples in SolrQuerySyntax) based on a constant date or NOW.

Things other than these will _not_ work as arguments. For example, you cannot currently use:

Arguments may _not_ be "classic" date fields

ms()

ms(a)

Note that this number can be negative for dates from before the epoch.

ms(a,b)

 

bf用函數計算某個字段的權重,如上例子中pub_date發佈日期的權重,point比如誠信指數,sale_count銷售數量

bf內字段必須是索引的,bf的函數查看solr api文檔 http://wiki.apache.org/solr/FunctionQuery

pf查詢字段,這樣在schema不用制定默認字段

qf對默認查詢增加權重比值,比如標題是content的1.9倍,值越大權重越大

這樣查詢就會計算如下的一個綜合評分值了

https://www.cnblogs.com/xiaolang8762400/p/7448929.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章