做搜索引擎避免不了排序問題,當排序沒有要求時,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的主要參數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多如下功能:
- 以不同的權值來搜索多個field。
- 限制查詢語法為一個小的集合並且用無語法錯誤。該特性是強制的並是不可配置的
- 整個搜索查詢的自動的短語boosting
- 便利的查詢boosting參數,通常同函數查詢一塊使用
- 能指定單詞匹配的最少個數,這取決於查詢串中的單詞數.
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變化通常的原因有以下幾點:
- 使用不同的boost因素讓短語增強的影響沒有壓倒性。一些經驗可以來引導你做這些調整。
- 忽略那些只有一個term的字段。比如唯一標識字段。
- 忽略那些含有太大的文本值的字段,因為它可能全使查詢效率大大降低。
- 使用一個具體相同值,但是使用不同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)
按照sort條件排序
第三:按照eidsmax設置的的公式計算出來的score結果來進行排序
搜索關鍵字匹配某些字段的打分比其他的字段要高(qf^)
對於某些字段,搜索字符串的密集度(phrase)的打分中占的比重(pf^)
bf部分是用來解決比較復雜的權重問題了,其中需要用到solr的查詢函數