solr入門之權重排序方法初探之使用edismax改變權重


做搜索引擎避免不了排序問題,當排序沒有要求時,solr有自己的排序打分機制及sorce字段

1.無特殊排序要求時,根據查詢相關度來進行排序(solr自身規則)

2.當涉及到一個字段來進行相關度排序時,可以直接使用solr的sort功能來實現

3.對多個字段進行維度的綜合打分排序(這個應該才是重點,內容)

 

使用Solr搭建搜索引擎很容易,但是如何制定合理的打分規則(boost)做排序卻是一個很頭痛的事情。Solr本身的排序打分規則是繼承自 Lucene的文本相關度的打分即boost,這一套算法對於通用的提供全文檢索的服務來講,已經夠用了,但是對於一些專門領域的搜索來講,文本相關度的 打分是不合適的。
如何來定制適合自身業務的排序打分規則(boost)呢?經過這段時間的思考與實踐,想到了如下三個方法

  • 1、定制Lucene的boost算法,加入自己希望的業務規則;
  • 2、使用Solr的edismax實現的方法,通過bf查詢配置來影響boost打分。
  • 3、在建索引的schema時設置一個字段做排序字段,通過它來影響文檔的總體boost打分。

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

  • 第一種方法技術難度要求較高,需要讀懂Lucene的boost打分算法,在代碼層做定制.
  • 第二種方式就簡單不少,不過因為受限於edismax提供的方法,所以有些局限性。
  • 第三種排序可完全消除文本相關性打分的影響,文本檢索匹配邏輯只負責打到匹配的項,排序由自定義字段處理。

 

上面是從網上收集的資料,可能還有別的解決辦法,這里就不再說了.相對而言,我們付出成本最低的解決辦法就是使用solr自身提供的權重計算方法 :

dismax和edismax來進行重新的權重計算排序.下面我們重點收集相關信息和對其進行真正的項目實踐!

 

 

官方資料:
使用dismax和edismax需要用到查詢函數具體資料:
官方資料:
中文資料:
 
dismax和edismax的區別--
看過這個博客大概可以總結出來,要使用復雜的權重排序時必須使用dismax或者edismax中的bf來重新設置score來進行自然的權重排序
 
因為edismax是dismax的升級版,以后都使用edismax來做.dismax來作為潛在研究
實踐:

 

下面講下dismax的主要參數qf,因為其他的參數沒有去分析。不能亂講。
qf  
例如:qf=fieldOne^2.3 fieldTwo fieldThree^0.4,  qf 參數時指定solr從哪些field中搜索。像下面的話就只會在fieldOne,fieldTwo fieldThree這三個field中搜索。如果你還指定了q參數,比如q=“hadoop”,那么solr會認為是到 fieldOne,fieldTwo, fieldThree這三個field中搜索hadoop,這三個是並集的關系。生成的query為:fieldOne:hadoop^2.3 | fieldTwo:hadoop | fieldThree:hadoop^0.4 所以你定義了dismax的話,你的查詢參數q就不要寫成類似q=“title:hadoop”這樣了。因為這樣的話最終的查詢 為:fieldOne:title:hadoop^2.3 | fieldTwo:title:hadoop | fieldThree:title:hadoop^0.4 除非你的這幾個field里有“title:hadoop”這樣的詞存在,否則是查不到結果的。

 

 

 http://blog.csdn.net/qing419925094/article/details/40924465

Solr 支持多種查詢解析,給搜索引擎開發人員提供靈活的查詢解析。Solr 中主要包含這幾個查詢解析器:標准查詢解析器、DisMax 查詢解析器,擴展 DisMax 查詢解析器(eDisMax)

Dismax

Dismax handler比standard handler多如下功能:

  1. 以不同的權值來搜索多個field。
  2. 限制查詢語法為一個小的集合並且用無語法錯誤。該特性是強制的並是不可配置的
  3. 整個搜索查詢的自動的短語boosting
  4. 便利的查詢boosting參數,通常同函數查詢一塊使用
  5. 能指定單詞匹配的最少個數,這取決於查詢串中的單詞數.

Dismax query parser

這里提到的所有應用於dismax的也都適用於edismax,除非明確說明不適用。其實edismax就是打算在未來的發布版本中替代dismax的。

Lucene DisjunctionMaxQuery

dismax可以查詢多個field,並且每個field使用不同的boost。這個功能是由lucene的DisjunctionMaxQuery查詢 類型來支持。以下的討論都是高級內容,不用刻意理解。只是記住dismax針對多個字段的查詢會設置tie參數為0.1,這也是合理的選擇。

舉個例子。如果有一個簡單查詢rock。dismax可能會將它配置為DisjunctionMaxQuery為fieldA:rock2 fieldB:rock1.2 fieldC:rock0.5, 如果是boolean查詢的話會跟這個查詢有些不同,不同的地方也就是得分。類似的boolean查詢的得分會基於這三個條文的總和,也就是 DisjunctionMaxQuery會使用每一個的最大值。針對多個字段查詢同一個term的情況,並且有些字段相對於另一些字段更重要,那么 dismax應該更好的處理得分。API文檔中的一個例子對這個特征的解釋是,如果用戶查詢albino elephant,那么假如有一種情況是albino匹配一個字段,elephant匹配另一個字段,另一種情況是albino匹配兩個字段,但是 elephant沒有一個匹配,那么dismax保證第一種情況的得分高於第二種情況。 另一個dismax得分的難題就是tie參數,tie的取值是0-1,默認是0,在實踐中設置為0.1效果最好。

Boosting:Automatic phrase boosting

dismax會把phrase查詢也就是引號引起來的查詢進行轉換,來改進得分。例如查詢billy joel 會轉換為+(billy joel) "billy joel"也就是說,如果一個文檔包含billy joel,那么它不僅匹配原始term而且還匹配billy和joel,也就是匹配三個term,如果另一個文檔不匹配短語billy joel,只是含有兩個單詞,那么lucene的得分算法會給第一個文檔更高的得分。

Configuring automatic phrase boosting

automatic phrase boosting默認是不啟用的。要使用的話可以使用pf參數,就是phrase fields的縮寫。語法與qf相同。用相同的值作為開始並做相應的調整,從qf到pf變化通常的原因有以下幾點:

  1. 使用不同的boost因素讓短語增強的影響沒有壓倒性。一些經驗可以來引導你做這些調整。
  2. 忽略那些只有一個term的字段。比如唯一標識字段。
  3. 忽略那些含有太大的文本值的字段,因為它可能全使查詢效率大大降低。
  4. 使用一個具體相同值,但是使用不同analyzed的字段來替換這個字段

同樣的強烈推薦使用common-grams和shingling來提高執行效率。

Phrase slop configuration

phrase slop就是短語后跟一個波浪線和一個數字,就像這樣"billy joel"~1 對於所有明確指定的短語查詢dismax會自動添加兩個參數來設置slop:qs和phrase boosting:ps,如果slop沒有指定那么就相當於是0。 10

Partial phrase boosting

如果查詢的是兩個單詞,那么edismax支持增強為連續的單詞對,如果是三個單詞,那么可以增強三倍。例如查詢how now brown cow 會變為: +(how now brown cow) "how now brown cow" "how now" "now brown" "brown cow" "how now brown" "now brown cow" 這個特征不會被ps參數影響,ps只應用於entire phrase boost。

Boosting:boost queries

dismax的bq參數可以用來指定多個查詢,類似於automatic phrase boost。以類似的方式被添加到用戶的查詢中。記住一點,boosting只是用來影響q參數指定的用戶查詢所匹配到的那些文檔的scoring。如果 匹配的結果還匹配bq查詢,那么這個文檔的得分會更高。 (: -r_type:aaa)2增強所有文檔得分,但是除了aaa。 boost queries不如boost functions有用。

Boosting:boost functions

boost functions提供一個強大的功能就是使用用戶設置的公式來對文檔的score進行計算。這里所說的公式也就是solr的function queries,使用bf參數來操作score。edismax支持boost參數來進行function query。可以使用bf或boost多次。

<str name="boost">recip(map(rord(r_event_date),0,0,99000),1,95000,95000)</str>

函數中不能有空格。bf和boost兩個參數其實並沒有以相同的方式解析。bf參數允許多種boost functions使用相同的參數,以空格分開,二者選一的話還是使用bf參數。還可以在bf參數中乘以因子在函數的結尾。比如100

 

 

 

Demo

搜索功能中比較復雜的是文檔的打分排序,solr中的打分規則繼承了lucene中的相關的打分規則,這里通過solr的dismax查詢解析器來支持復雜的打分

在打分的時候,會考慮以下因素,

搜索關鍵字匹配某些字段的打分比其他的字段要高(qf^)

對於某些字段,搜索字符串的密集度(phrase)的打分中占的比重(pf^)

其他復雜規則計算,比如銷售量、價格、賣家等級等等都可以作為考慮的因素,影響打分(bf)

http://10.1.1.58:8080/solr/select?defType=dismax&qf=name^100  subject ^1 &q=sony mp3&pf=name^100  subjec ^1&q.op=OR&bf=sum(recip(ms(NOW,last_modified),3.16e-11,1,1),div(1000,price))^100

這個查詢的含義是,在name和subject中搜索關鍵字sony mp3,name和subject在字段查詢中的比重分別為100、1(qf=name^100subject ^1);並且這兩個字段phrase的打分為

pf=name^100 subject ^1,也就是name占的比重大一些;其他還參考產品的價格和商品更新時間(bf=sum(recip(ms(NOW,last_modified),3.16e-11,1,1),div(1000,price))^100)

 

 

我得查詢
默認查詢--按照docid排序

 

 

 

 

按照sort條件排序

 

第三:按照eidsmax設置的的公式計算出來的score結果來進行排序

 

 

使用后感覺:
edismax主要就是用來改變score的作用,進而來進行自己想要的score默認排序
 
每個參數的意思大家可以百度的一下網上的資料或者看官方資料
 
其中幾個意思
q.alt 為主查詢未設置時使用的查詢條件(主查詢設置后不起用)

搜索關鍵字匹配某些字段的打分比其他的字段要高(qf^)

對於某些字段,搜索字符串的密集度(phrase)的打分中占的比重(pf^)

 

bf部分是用來解決比較復雜的權重問題了,其中需要用到solr的查詢函數

官方資料:
中文資料:
 
個人猜想:edismax應該是可以動態的來使用的,即可以在代碼中來進行表達式的生成工作
從而使你想要的每個方法的權重都是可以自定義的.這僅僅是猜想!下周一試驗一下是否可以實現!!


免責聲明!

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



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