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

				}
			});
相關文章
相關標籤/搜索