首页 > 代码库 > 在Lucene或Solr中实现高亮的策略
在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高亮,第二就是服务端高亮后返回给前台
后端高亮的流程:
前端高亮的流程:
三:优劣分析
后端高亮:
性能:并发量大的情况下,可能对server的性能造成一定影响。
可靠性:高,在浏览器禁用js脚本情况下,仍能够正常显示
前端高亮:
性能:由client渲染,相对性能稍高
可靠性:低,在浏览器禁用js脚本情况下,高亮失效
四:注意事项
前台高亮时,须要把句子分词后的词组。返回给前台js,便于正则替换,关于把句子分词,能够用lucene也能够用solr,方式分别例如以下:
在Lucene中:
Java代码
- /***
- *
- * @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 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(); }
在solr中,方式1:
Java代码
- /***
- * 依据字段类型分词并打印分词结果
- * @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 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()); } }
在solr中,方式2:
Java代码
- /***
- * 依据字段名分词并打印分词结果
- * @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());
- }
- }
/*** * 依据字段名分词并打印分词结果 * @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()); } }
最后欢迎大家扫码关注微信公众号:我是攻城师(woshigcs)。我们一起学习,进步和交流!(woshigcs)
本公众号的内容是有关搜索和大数据技术和互联网等方面内容的分享。也是一个温馨的技术互动交流的小家园,有什么问题随时都能够留言,欢迎大家来訪!
在Lucene或Solr中实现高亮的策略
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。