lucene4.7 高亮功能(八)
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
lucene4.7 高亮功能(八) 博客分類: 搜索引擎,爬蟲 java ?高亮功能一直都是全文檢索的一項非常優(yōu)秀的模塊,在一個標(biāo)準(zhǔn)的搜索引擎中,高亮的返回命中結(jié)果,幾乎是必不可少的一項需求,因為通過高亮,我們可以在我們的搜索界面上快速標(biāo)記出用戶的檢索關(guān)鍵詞,從而減少了用戶自己尋找想要的結(jié)果,在一定程度上大大提高了用戶的體驗性和友好度。?
那么,今天就來看下我們在Lucene中,怎么實現(xiàn)高亮,以及高亮的幾種實現(xiàn)方式。?
首先還是喜歡老生常談的來補(bǔ)充下高亮需要的熟悉的基本知識,當(dāng)然如果你只是需要實現(xiàn)效果,而不關(guān)注它的底層API,那么可以忽略此部分,不過還是要友好的提示一下,如果使用過程中出了點小問題,不會API,可是不容易解決的,除非你愿意各種google。?
要使用高亮,首先就得從索引時開始,因為需要高亮的字段,需要準(zhǔn)確的獲取位置信息,以及一些偏移量,如果信息不準(zhǔn)確,那么可能在結(jié)果中,就會出現(xiàn)一些莫名其妙的錯位,反映到網(wǎng)頁上就是標(biāo)注了不該標(biāo)注的字,沒有標(biāo)注該標(biāo)的內(nèi)容,所以這一點還是需要注意一下,在索引的時候,我們需要使用項向量記錄各個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 | 索引,分詞,存儲 |
由此看來,需要進(jìn)行高亮的內(nèi)容,是一定要存儲的,可能有一些比較大的文本,會比較占索引空間,從而影響檢索性能,當(dāng)然我們也可以使用外部存儲,關(guān)系型數(shù)據(jù)庫,nosql什么的都可以,此時,高亮可能就需要做另一些處理了,散仙在下文會介紹。?
下面我們來看下,高亮的需要用到的一些基本的類?
| 類 | 釋義 |
| SimpleHTMLFormatter | 常用的格式化Html標(biāo)簽器,提供一個構(gòu)造函數(shù)傳入高亮顏色標(biāo)簽,默認(rèn)使用黑色 |
| TokenSources | 提供靜態(tài)方法,支持從數(shù)據(jù)源中獲取TokenStream,進(jìn)行token處理 |
| Highlighter | 負(fù)責(zé)獲取匹配上的高亮片段 |
| QueryScorer | 對命中結(jié)果進(jìn)行評分操作 |
| Fragmenter | 將原始字符串拆分成獨(dú)立的片段 |
| NullFragmenter | 對較短的域進(jìn)行整體高亮 |
| FastVectorHighlighter | 基于快速高亮 |
| Encoder | 提供一些實現(xiàn)類,對html文本操作,如,去掉一些特殊匹配符號<,>? and so on,及一些其他的非ASCII特殊字符。 |
下面我們先來看下散仙的幾條測試數(shù)據(jù)內(nèi)容:?
| 1 2 3 4 5 | id: 1?????? name:??中國是一個偉大的國家,我們中國人都是好樣的哈哈,中國永遠(yuǎn)是強(qiáng)大的???content:??你好人民 id: 2?????? name:??我們有一個家它的名字是中國???content:??中國的大地,富饒 id: 3?????? name:??我們的中國,我們的大地都是人民的希望的???content:??如果不在片段中生成一些字段的話 id: 4?????? name:?? 2014 年此時此刻你在做什么的啊???content:??哈哈鋤禾日當(dāng)午 id: 5?????? name:??當(dāng)你孤單時你會想起誰,你想不想找個人來陪???content:??我永遠(yuǎn)不孤單啊 |
?
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>" ); //定制高亮標(biāo)簽 ????????? ???????? Highlighter??highlighter= new? Highlighter(fors,score); //高亮分析器 ???????? //?highlighter.setMaxDocCharsToAnalyze(1);//設(shè)置高亮處理的字符個數(shù) ???????? 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); //獲取高亮的片段,可以對其數(shù)量進(jìn)行限制 ????????????? ????????????? System.out.println( "高亮的片段?=====>" +str); ???????? } |
輸出結(jié)果如下
?| 1 2 3 | 高亮的片段?=====>中國是一個<span?style= "color:red;" >偉大</span><span?style= "color:red;" >的</span>國家,我們中國人都是好樣<span?style= "color:red;" >的</span>哈哈,<span?style= "color:red;" >中國</span>永遠(yuǎn)是強(qiáng)大<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,這個類可能會消耗更多的存儲空間,來換取更好的性能,當(dāng)然除了性能上提升外,它還有一個非常炫的功能,支持多種顏色標(biāo)記,高亮關(guān)鍵字,除此之外還支持Ngram的域,以及智能合并相鄰高亮短語.?
我們來看下散仙快速高亮的3條測試數(shù)據(jù):?
| 1 2 3 | id: 2?????? name:??中國(China),位于東亞,是一個以華夏文明為主體、中華文化為基礎(chǔ),以漢族為主要種族的統(tǒng)一多民族國家,通用漢語。中國疆域內(nèi)的各個民族統(tǒng)稱為中華民族,龍是中華民族的象征。???content:??中國是世界四大文明古國之一,有著悠久的歷史,距今約 5000 年前,以中原地區(qū)為中心開始出現(xiàn)聚落組織進(jìn)而成國家和朝代,后歷經(jīng)多次演變和朝代更迭,持續(xù)時間較長的朝代有夏、商、周、漢、晉、唐、宋、元、明、清等 id: 1?????? name:??中國的自古以來就是一個非常偉大的民族???content:??中國是一個世界人口大國,擁有 13 億多的人口. id: 3?????? name:??沒有根的野草,飄忽的命運(yùn)???content:??誰像你當(dāng)我寶,什么也做到,舊愛數(shù)足一塊布,在這一刻寫句號,只想跟你終老. |
核心代碼如下:
?| 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>");//定制高亮標(biāo)簽 ???????? //Highlighter??highlighter=new?Highlighter(fors,score);//高亮分析器 ???????? //FastVectorHighlighter?fastHighlighter=new?FastVectorHighlighter(); ???????? FragListBuilder?fragListBuilder= new? SimpleFragListBuilder(); ???????? //注意下面的構(gòu)造函數(shù)里,使用的是顏色數(shù)組,用來支持多種顏色高亮 ???????? 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);//設(shè)置高亮處理的字符個數(shù) ???????? for (ScoreDoc?sd:top.scoreDocs){ ?????????? ???????????? String?snippt=fastHighlighter2.getBestFragment(querys,?reader,?sd.doc,filed, 300 ); ?????????? ????????????? if (snippt!= null ){ ????????????????? System.out.println( "高亮的片段是:" +snippt); ????????????? }???? ???????? } |
結(jié)果如下,注意有多種顏色標(biāo)識:?
| 1 2 3 | 高亮的片段是:中國<b?style= "background:lawngreen" >的</b>自古以來就是一個非常<b?style= "background:yellow" >偉大</b><b?style= "background:lawngreen" >的</b>民族 高亮的片段是:中國(China),位于東亞,是一個以華夏文明為主體、中華文化為基礎(chǔ),以漢族為主要種族<b?style= "background:lawngreen" >的</b>統(tǒng)一多民族國家,通用漢語。中國疆域內(nèi)<b?style= "background:lawngreen" >的</b>各個民族統(tǒng)稱為<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>命運(yùn) |
3.下面來著重說一下,高亮的第三種方式,前臺高亮,散仙在上文曾提過,基于高亮的字段,必須的存儲,否則無法實現(xiàn)高亮標(biāo)注,當(dāng)然這種說法,只是對于后臺高亮而言的,那么對于大文本情況下,存儲到索引里是非常浪費(fèi)空間的,而且還有可能會影響到檢索速度,所以就提出了,第三種方式。?
在前臺進(jìn)行高亮,然后大文本字段,可以存儲在外部其他的數(shù)據(jù)源里面,需要標(biāo)記時,可以直接根據(jù)ID,或者某個字段,讀取數(shù)據(jù)然后通過JS正則在前端替換檢索的關(guān)鍵詞即可,在這之前需要做的一步就是,使用ajax把檢索的關(guān)鍵詞,傳入后臺進(jìn)行分詞,然后將結(jié)果返回前臺,進(jìn)行對分詞后的數(shù)據(jù),進(jìn)行匹配替換,再加上顏色標(biāo)記,就可以在前臺實現(xiàn)高亮了,這也是前臺高亮的實現(xiàn)原理,這種做法,在某些業(yè)務(wù)場景下,可以大大減少服務(wù)器壓力,通過客戶端減壓,以及不用再存儲一些向量信息,從而對系統(tǒng)的性能的提高,也是有很大幫助的。?
下面給出一個前臺高亮的截圖,注意用的是快速高亮的索引。?
附上前臺高亮的核心代碼?
| 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( "[*]=============================== " ) ????????????????????? }); ???????????????? } ???????????? }); |
至此,有關(guān)Lucene的高亮部分的內(nèi)容,散仙就總結(jié)到這里了,如果有什么不足之處,歡迎各位道友指出。大部分場景下,使用普通高亮就可以完成了,當(dāng)然無論使用那種方式,只要能滿足我們的業(yè)務(wù)就好了,很簡單的道理,會抓住老鼠的貓,就是好貓。
?感謝耐下心讀到此處的朋友^_^, Lucene交流群:324714439?
?
?
http://my.oschina.net/MrMichael/blog/220952
轉(zhuǎn)載于:https://my.oschina.net/xiaominmin/blog/1597434
總結(jié)
以上是生活随笔為你收集整理的lucene4.7 高亮功能(八)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里云服务器被挖矿病毒minerd***
- 下一篇: java json lib 日期