2019独角兽企业重金招聘Python工程师标准>>>

lucene4.7 高亮功能(八) 博客分类: 搜索引擎,爬虫 java

高亮功能一直都是全文检索的一项非常优秀的模块,在一个标准的搜索引擎中,高亮的返回命中结果,几乎是必不可少的一项需求,因为通过高亮,我们可以在我们的搜索界面上快速标记出用户的检索关键词,从而减少了用户自己寻找想要的结果,在一定程度上大大提高了用户的体验性和友好度。

那么,今天就来看下我们在Lucene中,怎么实现高亮,以及高亮的几种实现方式。 
首先还是喜欢老生常谈的来补充下高亮需要的熟悉的基本知识,当然如果你只是需要实现效果,而不关注它的底层API,那么可以忽略此部分,不过还是要友好的提示一下,如果使用过程中出了点小问题,不会API,可是不容易解决的,除非你愿意各种google。

要使用高亮,首先就得从索引时开始,因为需要高亮的字段,需要准确的获取位置信息,以及一些偏移量,如果信息不准确,那么可能在结果中,就会出现一些莫名其妙的错位,反映到网页上就是标注了不该标注的字,没有标注该标的内容,所以这一点还是需要注意一下,在索引的时候,我们需要使用项向量记录各个token的位置信息,这很简单,代码如下:

?
1
2
3
4
5
6
  FieldType type= new  FieldType(TextField.TYPE_STORED); 
  type.setStoreTermVectorOffsets( true ); //记录相对增量
  type.setStoreTermVectorPositions( true ); //记录位置信息
  type.setStoreTermVectors( true ); //存储向量信息
  type.freeze(); //阻止改动信息
  Field field= new  Field( "字段名" "值" , type); //示例

简单说下,TextField的2个枚举变量的意思

变量名 释义
TYPE_NOT_STORED 索引,分词,不存储
TYPE_STORED 索引,分词,存储


由此看来,需要进行高亮的内容,是一定要存储的,可能有一些比较大的文本,会比较占索引空间,从而影响检索性能,当然我们也可以使用外部存储,关系型数据库,nosql什么的都可以,此时,高亮可能就需要做另一些处理了,散仙在下文会介绍。 

下面我们来看下,高亮的需要用到的一些基本的类 

释义
SimpleHTMLFormatter 常用的格式化Html标签器,提供一个构造函数传入高亮颜色标签,默认使用黑色
TokenSources 提供静态方法,支持从数据源中获取TokenStream,进行token处理
Highlighter 负责获取匹配上的高亮片段
QueryScorer 对命中结果进行评分操作
Fragmenter 将原始字符串拆分成独立的片段
NullFragmenter 对较短的域进行整体高亮
FastVectorHighlighter 基于快速高亮
Encoder 提供一些实现类,对html文本操作,如,去掉一些特殊匹配符号<,>  and so on,及一些其他的非ASCII特殊字符。

下面我们先来看下散仙的几条测试数据内容: 

?
1
2
3
4
5
id: 1       name:  中国是一个伟大的国家,我们中国人都是好样的哈哈,中国永远是强大的   content:  你好人民
id: 2       name:  我们有一个家它的名字是中国   content:  中国的大地,富饶
id: 3       name:  我们的中国,我们的大地都是人民的希望的   content:  如果不在片段中生成一些字段的话
id: 4       name:   2014 年此时此刻你在做什么的啊   content:  哈哈锄禾日当午
id: 5       name:  当你孤单时你会想起谁,你想不想找个人来陪   content:  我永远不孤单啊

1,测试普通高亮的核心代码: 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
     String filed= "name" ;
         QueryParser query= new  QueryParser(Version.LUCENE_44, filed,  new  IKAnalyzer( false ));
      
         Query q=query.parse( "伟大的中国" ); //测试字段
         TopDocs top=searcher.search(q,  100 );
         QueryScorer score= new  QueryScorer(q, filed); //传入评分
         SimpleHTMLFormatter fors= new  SimpleHTMLFormatter( "<span style=\"color:red;\">" "</span>" ); //定制高亮标签
         
         Highlighter  highlighter= new  Highlighter(fors,score); //高亮分析器
         // highlighter.setMaxDocCharsToAnalyze(1);//设置高亮处理的字符个数
         for (ScoreDoc sd:top.scoreDocs){
             Document doc=searcher.doc(sd.doc);
             String name=doc.get(filed);
             TokenStream token=TokenSources.getAnyTokenStream(searcher.getIndexReader(), sd.doc, filed,  new  IKAnalyzer( true )); //获取tokenstream
             Fragmenter  fragment= new  SimpleSpanFragmenter(score);
             highlighter.setTextFragmenter(fragment);
             String str=highlighter.getBestFragment(token, name); //获取高亮的片段,可以对其数量进行限制
             
              System.out.println( "高亮的片段 =====>" +str);
         }

输出结果如下

?
1
2
3
高亮的片段 =====>中国是一个<span style= "color:red;" >伟大</span><span style= "color:red;" >的</span>国家,我们中国人都是好样<span style= "color:red;" >的</span>哈哈,<span style= "color:red;" >中国</span>永远是强大<span style= "color:red;" >的</span>
高亮的片段 =====>我们<span style= "color:red;" >的</span><span style= "color:red;" >中国</span>,我们<span style= "color:red;" >的</span>大地都是人民<span style= "color:red;" >的</span>希望<span style= "color:red;" >的</span>
高亮的片段 =====>我们有一个家它<span style= "color:red;" >的</span>名字是<span style= "color:red;" >中国</span>

2,快速高亮,FastVectorHighlighter,这个类可能会消耗更多的存储空间,来换取更好的性能,当然除了性能上提升外,它还有一个非常炫的功能,支持多种颜色标记,高亮关键字,除此之外还支持Ngram的域,以及智能合并相邻高亮短语. 
我们来看下散仙快速高亮的3条测试数据: 

?
1
2
3
id: 2       name:  中国(China),位于东亚,是一个以华夏文明为主体、中华文化为基础,以汉族为主要种族的统一多民族国家,通用汉语。中国疆域内的各个民族统称为中华民族,龙是中华民族的象征。   content:  中国是世界四大文明古国之一,有着悠久的历史,距今约 5000 年前,以中原地区为中心开始出现聚落组织进而成国家和朝代,后历经多次演变和朝代更迭,持续时间较长的朝代有夏、商、周、汉、晋、唐、宋、元、明、清等
id: 1       name:  中国的自古以来就是一个非常伟大的民族   content:  中国是一个世界人口大国,拥有 13 亿多的人口.
id: 3       name:  没有根的野草,飘忽的命运   content:  谁像你当我宝,什么也做到,旧爱数足一块布,在这一刻写句号,只想跟你终老.

核心代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
     Query q=query.parse( "伟大的中华民族" );
         TopDocs top=searcher.search(q,  100 );
         //QueryScorer score=new QueryScorer(q, filed);
         //SimpleHTMLFormatter fors=new SimpleHTMLFormatter("<span style=\"color:red;\">", "</span>");//定制高亮标签
         //Highlighter  highlighter=new Highlighter(fors,score);//高亮分析器
         //FastVectorHighlighter fastHighlighter=new FastVectorHighlighter();
         FragListBuilder fragListBuilder= new  SimpleFragListBuilder();
         //注意下面的构造函数里,使用的是颜色数组,用来支持多种颜色高亮
         FragmentsBuilder fragmentsBuilder=  new  ScoreOrderFragmentsBuilder(BaseFragmentsBuilder.COLORED_PRE_TAGS,BaseFragmentsBuilder.COLORED_POST_TAGS);
         
       
         FastVectorHighlighter fastHighlighter2= new  FastVectorHighlighter( true true , fragListBuilder, fragmentsBuilder);
         FieldQuery querys=fastHighlighter2.getFieldQuery(q); //reader是传入的流
         
         // highlighter.setMaxDocCharsToAnalyze(1);//设置高亮处理的字符个数
         for (ScoreDoc sd:top.scoreDocs){
          
             String snippt=fastHighlighter2.getBestFragment(querys, reader, sd.doc,filed, 300 );
          
              if (snippt!= null ){
                  System.out.println( "高亮的片段是:" +snippt);
              }    
         }

结果如下,注意有多种颜色标识:

?
1
2
3
高亮的片段是:中国<b style= "background:lawngreen" >的</b>自古以来就是一个非常<b style= "background:yellow" >伟大</b><b style= "background:lawngreen" >的</b>民族
高亮的片段是:中国(China),位于东亚,是一个以华夏文明为主体、中华文化为基础,以汉族为主要种族<b style= "background:lawngreen" >的</b>统一多民族国家,通用汉语。中国疆域内<b style= "background:lawngreen" >的</b>各个民族统称为<b style= "background:aquamarine" >中华民族</b>,龙是<b style= "background:aquamarine" >中华民族</b><b style= "background:lawngreen" >的</b>象征。
高亮的片段是:没有根<b style= "background:lawngreen" >的</b>野草,飘忽<b style= "background:lawngreen" >的</b>命运

3.下面来着重说一下,高亮的第三种方式,前台高亮,散仙在上文曾提过,基于高亮的字段,必须的存储,否则无法实现高亮标注,当然这种说法,只是对于后台高亮而言的,那么对于大文本情况下,存储到索引里是非常浪费空间的,而且还有可能会影响到检索速度,所以就提出了,第三种方式。

在前台进行高亮,然后大文本字段,可以存储在外部其他的数据源里面,需要标记时,可以直接根据ID,或者某个字段,读取数据然后通过JS正则在前端替换检索的关键词即可,在这之前需要做的一步就是,使用ajax把检索的关键词,传入后台进行分词,然后将结果返回前台,进行对分词后的数据,进行匹配替换,再加上颜色标记,就可以在前台实现高亮了,这也是前台高亮的实现原理,这种做法,在某些业务场景下,可以大大减少服务器压力,通过客户端减压,以及不用再存储一些向量信息,从而对系统的性能的提高,也是有很大帮助的。

下面给出一个前台高亮的截图,注意用的是快速高亮的索引。 

附上前台高亮的核心代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
     $.ajax({
                 type : "post" ,
                 url:  "getContent" ,
                 data: "str=" +str,
                 dataType: "json" ,
                 async: false ,
                 success: function (msg){
                 // alert(msg);
                  $( "#div" ).empty();
                      $.each(msg,  function (i, n) {
                          var  temp= ""
                   for ( var  i=0;i<shu.length;i++){
                    if (shu[i]!= "" ){
                  n.name=n.name.replace( new  RegExp(shu[i], 'g' ),  "<span style=\"color:red;\">" +shu[i]+ "</span>" );
                
                          }
                         }
                           $( "#div" ).append( "[*]" +n.name+ "
" );
                           $( "#div" ).append( "[*]===============================
" )
                      });
                 }
             });

至此,有关Lucene的高亮部分的内容,散仙就总结到这里了,如果有什么不足之处,欢迎各位道友指出。大部分场景下,使用普通高亮就可以完成了,当然无论使用那种方式,只要能满足我们的业务就好了,很简单的道理,会抓住老鼠的猫,就是好猫。

 感谢耐下心读到此处的朋友^_^, Lucene交流群:324714439 

http://my.oschina.net/MrMichael/blog/220952

转载于:https://my.oschina.net/xiaominmin/blog/1597434

lucene4.7 高亮功能(八)相关推荐

  1. 使用prismjs为网站添加代码高亮功能

    prismjs 是一款轻量.可扩展的代码语法高亮库,使用现代化的 Web 标准构建,使用 Prismjs 可以快速为网站添加代码高亮功能,支持超过113中编程语言,还支持多种插件,是简洁.高效的代码高 ...

  2. QT QTextEdit富文本插入字体-表格-编号-图片-查找-语法高亮功能

    QT QTextEdit富文本插入字体-表格-编号-图片与查找功能,输入char 自动变成蓝色-语法高亮功能 QTQTextEdit富文本插入字体-表格-编号-图片-查找-语法高亮功能.rar-QT文 ...

  3. Byr论坛 新增语法高亮功能

    经过不懈地努力,nForum新增语法高亮功能,在发文/发信时,可以使用语法高亮操作使不同的语言能按其语法特征高亮显示,如下图: 发文/发信后,语法高亮效果如下图: 目前支持的语言有:ActionScr ...

  4. solrj高亮功能简单应用

    上篇文章介绍了solrj的简单用法,这篇文章进一步介绍一下solr的高亮功能. 高亮的原理其实就是在查询到的结果中,直接在需要高亮的数据前后添加html标签, 从而实现高亮显示. 那么我们只需要设置需 ...

  5. Qt中文本编辑器实现语法高亮功能(Qscitinlla)

    Scintilla是一个免费.跨平台.支持语法高亮的编辑控件.它完整支持源代码的编辑和调试,包括语法高亮.错误指示.代码完成(code completion)和调用提示(call tips).能包含标 ...

  6. 原生JS实现代码高亮功能

    实现步骤 分析如何实现该功能 了解词法结构 Javascript的产生式 少废话,上代码 分析如何实现该功能 平时我们在使用一些代码编辑器或者Markdown时很好奇它的代码高亮是如何 实现的.其实原 ...

  7. Vue中如何实现代码高亮功能?

    目录 1.下载依赖 2.在main.js文件中导入包 3.同样是在main.js文件中自定义一个指令 4.在vue文件中使用指令 5.效果展示 1.下载依赖 npm install highlight ...

  8. 前端实现搜索关键字高亮功能:

    /* 联想建议*/ <template><div class="searchSuggestionMain"><van-cell v-for=" ...

  9. vue 搜索关键字并实现高亮功能

    搜索关键字并让关键字高亮,主要是将input搜索框绑定数据,然后传给后端,调用接口获得搜索到的列表,然后将得到的列表中的关键字做一个替换 效果图: 搜索框部分代码: <div class=&qu ...

最新文章

  1. JavaScript简单重写构造器的原型
  2. 选redis还是memcache?
  3. Sublime Text开发Quick-Cocos2d-x环境搭建(Mac)
  4. Spring-AOP @AspectJ切点函数之execution()
  5. python无法识别vim中文代码
  6. RocketMQ的核心概念,一一梳理清楚
  7. OpenCV--矩阵操作总结
  8. java工程师面试题:如何判断链表有环?
  9. Java中什么时候throws_何时在Java方法声明中使用throws?
  10. pyecharts显示所有x轴_30分钟学会pyecharts数据可视化
  11. 使用MesaSQLite入库CSV文件
  12. [转]jQuery ListBox Plugin(ListBox插件)
  13. 市场营销分析--页面广告统计
  14. mysql故障切换 java_javaoraclethin和oci连接方式实现多数据库的故障切换
  15. 13款最佳免费网络监控工具,网站监控软件的总结。
  16. 【数据挖掘】电商数据合集
  17. 苹果7信号天线内部位置_苹果7信号天线内部位置_除了芯片还有天线!手机后壳换玻璃也是为5G准备...
  18. 计算机五笔是什么时候学的吗,电脑五笔输入法怎么学
  19. qq视频转码失败怎么办_迅捷视频转换器腾讯视频转换失败如何解决?
  20. Pathon简介和优势

热门文章

  1. linux redis release.c:37:10: fatal error: release.h: No such file or directory
  2. SQL数据库对象的建立
  3. masm汇编标号用法总结
  4. c++11=default,=delete
  5. Nmap Windows 版本时区显示乱码
  6. 四、MyBatis-映射文件
  7. Coursera-AndrewNg(吴恩达)机器学习笔记——第四周编程作业(多分类与神经网络)...
  8. 【Java面试题】34 List 、Map、Set 区别?
  9. 首届.NET Core开源峰会
  10. IE iframe 中 js 的 cookie 读写不到的解决办法