1. 程式人生 > >Solr結合Auto Complete實現自動提示

Solr結合Auto Complete實現自動提示

前言

在日常經常使用的搜尋中,我們經常會看到下面這種頁面。這種智慧提示,會向用戶友好的推薦可能使用者想查詢的關鍵詞。

不管是solr還是ES,實現上面這種效果的方式有很多,這裡主要是結合solr和jquery中的Autocomplete來實現上面的效果。

Solr中的智慧提示配置

首先需要說明,這裡使用的solr版本是5.5.5,其他版本可能有些許差別。但是基本原理應該是差不多的。對於solr服務的搭建,索引的生成,IK分詞器的配置,資料批量定時生成索引,這裡不做詳細介紹,有興趣的自行百度。這裡主要講解solr搭建好之後,如何配置實現Suggest功能。(其實Suggest功能和spellcheck是相輔相成的)。

首先在solrConfig.xml檔案中配置searchComponent和requestHandle

  <!--   solr中的suggest功能請求元件-->
  <searchComponent class="solr.SpellCheckComponent" name="suggest">
        <str name="queryAnalyzerFieldType">text_general</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>

然後再managed-schema檔案中配置需要智慧提示或者不全的域資訊

<field name="mc" type="string" indexed="true" stored="true"/>
<field name="xm" type="string" indexed="true" stored="true"/>
<field name="sfzhm" type="text_general" indexed="true" stored="true"/>
<field name="suggestion"  type="text_ik"  indexed="true"  stored="true"   
    termVectors="true" multiValued="true" />
  <copyField source="mc"   dest="suggestion" />
  <copyField source="sfzhm"   dest="suggestion" />
  <copyField source="xm"   dest="suggestion" />

上面中mc,sfzhm,xm是之前就已經定義好的域,我們這裡是需要對這三個域進行智慧提示,所以將這三個域整合到新建的suggestion的域中。(注意:這裡的suggestion要和solrConfig.xml檔案中配置searchComponent的域要保持一致)同時這裡新增了一個text_spell域型別。其實也是可以用text_general,text_IK,具體結合自己的使用專案需求。

在配置好上面的配置之後,我們需要重新生成索引,把之前的索引刪除掉,重新生成。我們在solr的管理介面上刪除之前的索引

點選commit之後就ok了,確認之前的舊索引刪除掉之後,我們重新按照新的配置檔案,生成新的索引。然後在solr控制檯中測試solr的自動提示效果

至此,solr本身的自動提示功能已經實現。

結合Autocomplete使用

上面solr的智慧提示已經完成,但是這是在solr控制檯中的效果,像百度那樣的實際效果是怎麼實現的呢?其實這需要藉助jquery的autocomplete外掛來實現

相關js和css檔案,具體資源可以去網上下載   https://jqueryui.com/download/

<link  rel="stylesheet" href="<%=basePath%>resources/newqkjsstyle/css/jquery-ui.css"/>
<script src="<%=basePath%>resources/newqkjsstyle/js/jquery.js"></script>
<script src="<%=basePath%>resources/newqkjsstyle/js/jquery-ui.js"></script>

頁面主要js指令碼如下

      $(function(){
        $("#searchText").autocomplete({
        	  source: function(request, response) {
                      var paravar=request.term;
        	      $.ajax({
        	      url: "<%=basePath%>solrController/suggest",
        	      dataType: "json",
        	      data: {
        	    	word:paravar
        	      },
        	      success: function(data) {
        	    	   var result=new Array();
        	    	   $.each(data,function(index,para){
        	    		   result.push(para.suggestion);
        	    	   });
        	    	   response($.map(result, function(item) {
        	              return {
        	                label: item,
        	                value: item
        	              }
        	            }));
        	      }
        	    });
        	  },
        	  minLength: 2
        	});
      }); 

對於solrController/suggest,我們是在後臺用solrj來發生suggest請求,具體程式碼如下

        /**
	 * solr中的suggest智慧補全功能
	 * @param word
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/suggest")
	public  List<Map<String, String>> suggest(String word) {
		List<Map<String, String>> wordList = new 
        ArrayList<Map<String, String>>();
		try {
			SolrQuery query = new SolrQuery();
			query.set("q",  word);// 查詢的詞
			query.set("qt", "/suggest");// 請求到suggest中
			query.set("spellcheck.count", "10");// 返回數量
			QueryResponse rsp = httpSolrServer.query(query);
			// 上面取結果的程式碼
			SpellCheckResponse re = rsp.getSpellCheckResponse();
			// 獲取拼寫檢查的結果集
			if (re != null) {
			for (Suggestion s : re.getSuggestions()) {
				List<String> list = s.getAlternatives();
				// 獲取所有 的檢索詞
				for (String spellWord : list) {
					Map<String, String> map = new 
							HashMap<String, String>();
					map.put("suggestion", spellWord);
					wordList.add(map);
				}
			}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return wordList;
	}

具體效果

總結

上面只是簡單的介紹了solr自動提示的配置,以及怎麼和autocomplete整合的小栗子!對於solr的其他功能,以及現在比較火的ES,後續在和大家一起學習!