在Lucene或Solr中實現高亮的策略

一:功能背景 

最近要作個高亮的搜索需求,之前也搞過,因此沒啥難度,只不過原來用的是Lucene,如今要換成Solr而已,在Lucene4.x的時候,散仙在之前的文章中也分析過如何在搜索的時候實現高亮,主要有三種方式,具體內容,請參考散仙之前的2篇文章:
第一:在Lucene4.3中實現高亮的方式 
http://qindongliang.iteye.com/blog/1953409
第二:在Solr4.3中服務端高亮的方式 
http://qindongliang.iteye.com/blog/2034270



二:方案探究 

從總體來說,主要有2種實現方式,第一就是前臺展現數據時使用js高亮,第二就是服務端高亮後返回給前臺 

後端高亮的流程: 



前端高亮的流程: 




三:優劣分析 

後端高亮: 
性能:併發量大的狀況下,可能對服務器的性能形成必定影響。 
可靠性:高,在瀏覽器禁用js腳本狀況下,仍能夠正常顯示 
前端高亮: 
性能:由客戶端渲染,相對性能稍高 
可靠性:低,在瀏覽器禁用js腳本狀況下,高亮失效 

四:注意事項 

前臺高亮時,須要把句子分詞後的詞組,返回給前臺js,便於正則替換,關於把句子分詞,能夠用lucene也能夠用solr,方式分別以下: 
在Lucene中: 

Java代碼   複製代碼  收藏代碼
  1. /***  
  2.      *   
  3.      * @param analyzer 分詞器  
  4.      * @param text  分詞句子  
  5.      * @throws Exception  
  6.      */  
  7.     public static void analyzer(Analyzer analyzer,String text)throws Exception{   
  8.                 TokenStream ts = analyzer.tokenStream("name",text);   
  9.                 CharTermAttribute term=ts.addAttribute(CharTermAttribute.class);   
  10.                 ts.reset();   
  11.                 while(ts.incrementToken()){   
  12.                     System.out.println(term.toString());   
  13.                 }   
  14.                 ts.end();   
  15.                 ts.close();   
  16.     }  
[

在solr中,方式1: 

Java代碼   複製代碼  收藏代碼
  1. /***  
  2.  * 根據字段類型分詞並打印分詞結果  
  3.  * @param text  
  4.  */  
  5. public static void showAnalysisType(String text)throws Exception{   
  6.   
  7.     String fieldType="ik";//分詞類型  
  8.     //調用服務   
  9.     FieldAnalysisRequest request = new FieldAnalysisRequest("/analysis/field");   
  10.     //設置類型   
  11.     request.addFieldType(fieldType);   
  12.     //設置待分詞的句子    
  13.     request.setFieldValue(text);   
  14.     //sc=private static HttpSolrClient sc=new HttpSolrClient("http://localhost:8983/solr/one");  
  15.     //獲得結果   
  16.     FieldAnalysisResponse response =request.process(sc);   
  17.     //獲得對應的Analysis   
  18.     Analysis as = response.getFieldTypeAnalysis(fieldType);   
  19.     List<String> results = new ArrayList<String>();   
  20.     //使用guava的庫,將iteratro對象轉換爲List對象   
  21.        List<AnalysisPhase> list=Lists.newArrayList(as.getIndexPhases().iterator());   
  22.        //取某一個fitler的分詞結果,由於一個fieldtype頗有可能配置了多個filter,每一步通過  
  23.        //filter的結果都不同,因此此處,要指定一個獲取分詞結果的filter,跟由於有關   
  24.        //因此散仙這裏就寫list.size-1了,注意此處的值,並非固定的   
  25.      for(TokenInfo token:list.get(list.size()-1).getTokens()){   
  26.          //獲得分詞數據結果   
  27.          results.add(token.getText());   
  28.      }   
  29.         
  30. }  
[ja

在solr中,方式2: 

Java代碼   複製代碼  收藏代碼
  1. /***  
  2.      * 根據字段名分詞並打印分詞結果  
  3.      * @param text  
  4.      */  
  5.     public static void showAnalysis(String text)throws Exception{   
  6.          //此處是字段名   
  7.          String fieldName="cpyName";   
  8.          //固定寫法   
  9.          FieldAnalysisRequest request = new FieldAnalysisRequest("/analysis/field");   
  10.          //添加field   
  11.          request.addFieldName(fieldName);   
  12.          //設置須要分詞的句子   
  13.          request.setFieldValue(text);   
  14.          //請求solr服務獲得結果   
  15.          FieldAnalysisResponse response =request.process(sc);   
  16.          //封裝結果,返回,可能供其後續調用的業務處理   
  17.          List<String> results = new ArrayList<String>();   
  18.          //根據字段名獲取結果    
  19.          Analysis as=response.getFieldNameAnalysis(fieldName);   
  20.          //使用guava工具包,轉iterator爲List   
  21.          List<AnalysisPhase> list=Lists.newArrayList(as.getIndexPhases().iterator());   
  22.          //打印分詞結果   
  23.          for(TokenInfo token:list.get(list.size()-1).getTokens()){   
  24.              System.out.println(token.getText());   
  25.          }   
  26.             
  27.     }  
相關文章
相關標籤/搜索