一:功能背景
最近要做个高亮的搜索需求,以前也搞过,所以没啥难度,只不过原来用的是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());
- }
-
- }
在Lucene或Solr中实现高亮的策略
原文:http://my.oschina.net/u/1027043/blog/485328