Lucene4.3开发之第八步之渡劫初期(八)

    高亮功能一直都是全文检索的一项很是优秀的模块,在一个标准的搜索引擎中,高亮的返回命中的结果,几乎是必不可少的一项需求,由于经过高亮,咱们能够在咱们的搜索页面上快速标记出用户的检索关键词,从而减小用户本身寻找想要的结果,在必定程度上大大提升了用户的体验性和友好度。
前端

    在本篇中,就来看下lucene中,怎么实现高亮,以及高亮的几种实现方式。
java

    接着补充下高亮须要熟悉的基本知识,固然若是能够你只是须要实现效果,而不关注它的底层api,那么能够忽略此部分,若是使用过程当中出了点小问题,不会api,但是不容易解决的。
ajax

    要使用高亮,首选就得从索引时开始,由于须要高亮的字段,须要准确的获取位置信息,以及一些偏移量,若是信息不许确,那么可能在结果中,就会出现一些莫名其妙的错位,反映到网页上就是标注了不应标注的字,没有标注该标注的内容,因此这一点上仍是须要注意一下,在索引的时候,咱们须要使用向量记录各个token的位置信息,代码以下:
正则表达式

 FieldType type=new FieldType(TextField.TYPE_STORED); 
 type.setStoreTermVectorOffsets(true);//记录相对增量
 type.setStoreTermVectors(true);//存储向量信息
 Field field=new Field("字段名", "值", type);//示例

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

由此看来,须要进行高亮的内容,是必定要存储的,可能有些比较大的问题,会比较占索引空间,从而影响检索性能,固然咱们也可使用外部存储,关系型数据库,nosql什么的均可以,此时,高亮可能就须要作另外一些处理了。数据库

下面咱们看下,高亮须要用到的一些基本的类:json

下面看几条测试数据内容:
api

一、测试普通高亮的核心代码:数组

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);
		}

输出结果以下:
服务器

二、快速高亮,FastVectorHighlighter,这个类可能会消耗更多的存储空间,来换取更好的性能,固然除了性能上提高外,它还有一个很是炫的功能,支持多种颜色标记,高亮关键字,除此以外还支持Ngram的域,以及智能合并相邻高亮短语。

下面看快速高亮的3条测试数据:

核心代码以下:

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);
			 }
		 
			 
		}

结果以下,有多种颜色标识:

三、下面着重讲一下,高亮的第三种方式,前台高亮,基于高亮的字段,必须是存储的,不然没法实现高亮标注,固然这种说法,只是对于后台高亮而言的,对于大文本状况下,存储到索引中是很是浪费空间的,,并且还可能会影响到检索的速度,因此就提出第三种方式。

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

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

附上核心代码:

$.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("[*]===============================
")
				 	});

				}
			});
相关文章
相关标签/搜索