資料來源:http://www.colorfuldays.org/category/program/solr/算法
搜索的智能提示目前是各大搜索的標配應用,主要做用是避免用戶輸入錯誤的搜索詞,同時將用戶引導到相應的關鍵詞搜索上。apache
做爲一個應用普遍的搜索引擎系統,Solr內置了智能提示功能,它在Solr裏叫作Suggest模塊.該模塊可選擇基於提示詞文本作智能提示,還支持經過針對索引的某個字段創建索引詞庫作智能提示。在諸多文檔中都推薦使用基於索引來作智能提示,所以咱們目前的實現也是採起該方案。ide
由於如今整個平臺是基於SPU的構建的,所以決定採用SPU關鍵屬性組合及類目名稱來作Suggest的索引字段。首先在schema.xml中添加存儲Suggest的新字段,以下:測試
<field name="suggestion" type="string" indexed="true" stored="true" ui
termVectors="true" multiValued="true"/>搜索引擎
在該field的配置中,FieldType的選擇很是關鍵,一般建議智能提示字段的FieldType不須要配置複雜的Analyzer,避免由於分詞致使智能提示的詞失控。spa
在solrconfig.xml文件中配置Suggest模塊,其中Suggest依賴於SpellChecker模塊,因此這兩個都須要配置。具體配置以下:component
<searchComponent class="solr.SpellCheckComponent" name="suggest">xml
<str name="queryAnalyzerFieldType">string</str>排序
<lst name="spellchecker">
<str name="name">suggest</str>
<str name="classname">org.apache.solr.spelling.suggest.Suggester</str>
<str name="lookupImpl">org.apache.solr.spelling.suggest.tst.TSTLookup</str>
<str name="field">suggestion</str>
<!-- the indexed field to derive suggestions from -->
<float name="threshold">0.0001</float>
<str name="spellcheckIndexDir">spellchecker</str>
<str name="comparatorClass">freq</str>
<str name="buildOnOptimize">true</str>
<!--<str name="buildOnCommit">true</str>-->
</lst>
</searchComponent>
<requestHandler class="org.apache.solr.handler.component.SearchHandler"
name="/suggest">
<lst name="defaults">
<str name="spellcheck">true</str>
<str name="spellcheck.dictionary">suggest</str>
<str name="spellcheck.onlyMorePopular">true</str>
<str name="spellcheck.extendedResults">false</str>
<str name="spellcheck.count">10</str>
<str name="spellcheck.collate">true</str>
</lst>
<arr name="components">
<str>suggest</str>
</arr>
</requestHandler>
<queryConverter name="phraseQueryConverter"
class="com.hqb360.solr.suggest.PhraseQueryConverter"/>
上述配置的具體說明可參照solr的官方文檔,下面對其中幾個容易疑惑的地方作一下說明
queryAnalyzerFieldType 配置參數
queryAnalyzerFieldType參數指定訪問suggest的SearchHandler處理查詢參數的Analyzer,若是指定的Analyzer很複雜的話,會致使suggest返回的結果不符合預期。在這們項目中,咱們現但願Analyzer不對查詢作任何的改變,所以選擇string。
spellcheck.dictionary的值必須與searchComponent中spellchecker標籤下<str name=」name」>suggest</str>配置對應。
Suggest返回結果的排序
spellchecker組件中的comparatorClass參數可配置Suggest返回結果的排序,目前有以下幾種可選方案:
Empty – in which case the default is used.
score – explicitly choose the default case
freq – Sort by frequency first, then score.
A fully qualified class name – Provide a custom comparator that implements Comparator<SuggestWord>.
可查看SuggestWordScoreComparator類瞭解更多細節
QueryConverter定製
上面的配置中,咱們定製了本身的QueryConverter,主要緣由是Solr默認的SpellQueryConvert是根據空格對查詢參數作分隔,致使 「nokia e」這樣的字符被看成「nokia」,「e」這樣的兩個字符處理,不符合咱們的要求。定製的PhraseQueryConverter代碼,須要打成jar包,放到Solr能訪問到的目錄下,在咱們系統中是${solr.solr.home}/lib目錄。
配置完成以後,重啓Solr後,訪問以下連接
http://192.168.100.10:8080/solr/suggest?q=motorola%20x
結果以下:
<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">0</int>
</lst>
<lst name="spellcheck">
<lst name="suggestions">
<lst name="motorola x">
<int name="numFound">10</int>
<int name="startOffset">0</int>
<int name="endOffset">10</int>
<arr name="suggestion">
<str>motorola xoom 3g版</str>
<str>motorola xt875</str>
<str>motorola xt300</str>
<str>motorola xt883</str>
<str>motorola xt702</str>
<str>motorola xt806</str>
<str>motorola xt800</str>
<str>motorola xt502</str>
<str>motorola xt882</str>
<str>motorola xt316</str>
</arr>
</lst>
<str name="collation">motorola xoom 3g版</str>
</lst>
</lst>
</response>
重啓Solr後,第一次訪問時須要在Suggest請求中添加spellcheck.build=true參數,用於建立spellchecker的索引。
經過threshold參數來限制一些不經常使用的詞不出如今智能提示列表中,當這個值設置過大時,可能致使結果太少,須要引發注意。
目前主要存在的問題是使用freq排序算法,返回的結果徹底基於索引中字符的出現次數,沒有兼顧用戶搜索詞語的頻率,所以沒法將一些熱門詞排在更靠前的位置。這塊可定製SuggestWordScoreComparator來實現,目前尚未着手作這件事情。
Posted in solr
Tags: solr, spellchecker, suggest