在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中:
- /***
- *
- * @param analyzer 分詞器
- * @param text 分詞句子
- * @throws Exception
- */
- public static void analyzer(Analyzer analyzer,String text)throws Exception{
- TokenStream ts = analyzer.tokenStream("name",text);
- CharTermAttribute term=ts.addAttribute(CharTermAttribute.class);
- ts.reset();
- while(ts.incrementToken()){
- System.out.println(term.toString());
- }
- ts.end();
- ts.close();
- }
- /***
- * 根據字段類型分詞並打印分詞結果
- * @param text
- */
- public static void showAnalysisType(String text)throws Exception{
-
- String fieldType="ik";//分詞類型
- //調用服務
- FieldAnalysisRequest request = new FieldAnalysisRequest("/analysis/field");
- //設置類型
- request.addFieldType(fieldType);
- //設置待分詞的句子
- request.setFieldValue(text);
- //sc=private static HttpSolrClient sc=new HttpSolrClient("http://localhost:8983/solr/one");
- //獲得結果
- FieldAnalysisResponse response =request.process(sc);
- //獲得對應的Analysis
- Analysis as = response.getFieldTypeAnalysis(fieldType);
- List<String> results = new ArrayList<String>();
- //使用guava的庫,將iteratro對象轉換爲List對象
- List<AnalysisPhase> list=Lists.newArrayList(as.getIndexPhases().iterator());
- //取某一個fitler的分詞結果,由於一個fieldtype頗有可能配置了多個filter,每一步通過
- //filter的結果都不同,因此此處,要指定一個獲取分詞結果的filter,跟由於有關
- //因此散仙這裏就寫list.size-1了,注意此處的值,並非固定的
- for(TokenInfo token:list.get(list.size()-1).getTokens()){
- //獲得分詞數據結果
- results.add(token.getText());
- }
-
- }
- /***
- * 根據字段名分詞並打印分詞結果
- * @param text
- */
- public static void showAnalysis(String text)throws Exception{
- //此處是字段名
- String fieldName="cpyName";
- //固定寫法
- FieldAnalysisRequest request = new FieldAnalysisRequest("/analysis/field");
- //添加field
- request.addFieldName(fieldName);
- //設置須要分詞的句子
- request.setFieldValue(text);
- //請求solr服務獲得結果
- FieldAnalysisResponse response =request.process(sc);
- //封裝結果,返回,可能供其後續調用的業務處理
- List<String> results = new ArrayList<String>();
- //根據字段名獲取結果
- Analysis as=response.getFieldNameAnalysis(fieldName);
- //使用guava工具包,轉iterator爲List
- List<AnalysisPhase> list=Lists.newArrayList(as.getIndexPhases().iterator());
- //打印分詞結果
- for(TokenInfo token:list.get(list.size()-1).getTokens()){
- System.out.println(token.getText());
- }
-
- }
歡迎關注本站公眾號,獲取更多信息