?
一、背景
? 搜索的智能提示是一個搜索應用的標配,主要作用是避免用戶輸入錯誤的搜索詞,并將用戶引導到相應的關鍵詞上,提升用戶體驗。
? 由于中文的特點,如果搜索自動提示可以支持拼音的話會給用戶帶來更大的方便,免得切換輸入法。
二、目標
- 基于用戶的歷史搜索關鍵字進行提示
- 同時支持漢字,拼音輸入
- 支持前綴匹配,比如輸入“ch”可能提示出“重慶”
- 支持縮寫輸入,比如輸入“cq”能提示出“重慶”
- 多音字支持,比如輸入“chongqing”或者“zhongqing”都能提示出“重慶”
- 輸出結果,根據用戶查詢關鍵字的頻率進行排序,暫時不考慮個性化需求
三、分析與解決方案
? ? ? ?假設我們的搜索應用是基于solrcloud實現的,主要是對商家信息進行搜索,包括商家名稱(store_name)、商家地址(address)。
? ? ? ?(1). 用戶每天輸入大量的查詢關鍵字,我們把查詢的關鍵字記錄下來,目前通過異步隊列寫入到mysql中,后期考慮寫入到hbase中
? ? ? ?(2). 用戶輸入的關鍵字可能是漢字、數字,英文,拼音,特殊字符等等,由于需要實現拼音提示,所以我們需要把漢字轉換成拼音,java中考慮使用pinyin4j組件實現轉換。
? ? ? ?(3). 漢字轉換拼音的過程中,順便提取出拼音縮寫,如“chongqing”,"zhongqing"--->"cq","zq"
? ? ? ?(4). 要支持多音字提示,對查詢串轉換成拼音后,需要實現一個全排列組合,考慮到查詢串可能比較長導致全排列比較的,具體算法需要做限制處理。
?
Solr Suggest實現智能提示
? ? ?首先Solr作為一個應用廣泛的搜索引擎系統,它內置了智能提示功能,叫做Suggest模塊。該模塊有兩種可選方案做智能提示:
? ? ? (1)、基于提示詞文本做智能提示
? ? ? (2)、基于索引中得某個字段建立索引詞庫做智能提示
? ? ?suggest的配置相對簡單, 下面開始寫 主要是使方式,?自定義的建議詞文本,放在跟solrconfig.xml同一級目錄下即可
? ? ?例如:solr\solr_home\collections\collection1\conf\suggest.txt?
?
下面給出suggest在solrconfig.xml里配置的代碼( 中文信息注意刪去 ) ??配置如下:
<searchComponent name="suggest" class ="solr.SpellCheckComponent"> <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">my_word</str> < float name="threshold">0.0001</ float > <!-- 使用自定義suggest詞庫詞--> <str name="sourceLocation">suggest.txt</str> <str name="spellcheckIndexDir">spellchecker</str>
<str name="comparatorClass">freq</str> <str name="buildOnOptimize"> true </str> <str name="buildOnCommit"> true </str> </lst> </searchComponent> <requestHandler name="/suggest" class ="org.apache.solr.handler.component.SearchHandler"> <lst name="defaults"> <str name="spellcheck"> true </str> <str name="spellcheck.dictionary">suggest</str> <str name="spellcheck.count">10</str> <str name="spellcheck.onlyMorePopular"> true </str> <str name="spellcheck.extendedResults"> false </str> <str name="spellcheck.collate"> true </str> <!--<str name="spellcheck.build"> true </str> --> </lst> <arr name="components"> <str>suggest</str> </arr> </requestHandler>
說明:
?1.solr的suggest基于solr.SpellCheckComponent
?2.queryAnalyzerFieldType 參數為string,在這不要定義復雜分詞,如果是根據某一個索引字段,意義不大
?3.field字段名,表示基于schema中的某一個索引字段
?4.threshold限制一些不常用的詞出現,值越大過濾紙越多
?5.sourceLocation用于設置字典,如果有一個字典能記錄用戶常搜索的字, 更靈活的控制,可以存放一些高質量的 query短語
?6.spellcheckIndexDir如果已經設置spellcheck,那么可以在此制定目錄
?7.字典格式如下
# This is a sample dictionary file.
acquire
accidentally\t2.0
accommodate\t3.0
文本格式utf-8,#開頭表示注釋,被忽略
每一個詞一行,后面帶權重
?8.配置詞典后在requestHandler中設置spellcheck.onlyMorePopular為true,可以根據權重排序
?9.spellcheck.count返回行
??配置完成重啟服務后,設置參數suggest/?spellcheck.build=true來創建spellchecker的索引
?然后輸入:http://ip:port/corename/suggest?q=xxx進行搜索了
?接下來就是前臺js實現的問題了。
?當然也可以通過solrj來進行搜索
CommonsHttpSolrServer server = new CommonsHttpSolrServer( "http://ip:port/corename/" ); SolrQuery params = new SolrQuery(); String token = "Solr" ; params.set( "qt", "/suggest" ); params.set( "q" , token); params.set( "spellcheck.build", "true" ); QueryResponse response = null ; try { response = server.query(params); System.out.println( "查詢耗時:" + response.getQTime()); } catch (SolrServerException e) { System.err.println(e.getMessage()); e.printStackTrace(); } catch (Exception e) { System.err.println(e.getMessage()); e.printStackTrace(); } finally { } SpellCheckResponse spellCheckResponse = response .getSpellCheckResponse(); if (spellCheckResponse != null ) { List <Suggestion> suggestionList = spellCheckResponse .getSuggestions(); for (Suggestion suggestion : suggestionList) { System.out.println( "Suggestions NumFound: " + suggestion.getNumFound()); System.out.println( "Token: " + suggestion.getToken()); System.out.print( "Suggested: " ); List <String> suggestedWordList = suggestion.getAlternatives(); for (String word : suggestedWordList) { System.out.println(word + ", " ); } System.out.println(); } }
?
-----OK
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
