bbmonkey62笨笨猴

          中文分詞

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            2 隨筆 :: 0 文章 :: 38 評(píng)論 :: 0 Trackbacks

          ShuzhenAnalyzer-1.1.8與上一版本1.1.7在功能上沒(méi)有任何區(qū)別,版本的升級(jí)是為了能夠與lucene1.1.8一起使用。

          對(duì)于搜索引擎而言,如果是提供一個(gè)類似于Google那樣的web界面搜索的話,那對(duì)搜索結(jié)果進(jìn)行高亮顯示就很重要且必要了,不然將是非常不友好的,本篇文章就是介紹在lucene中應(yīng)用HighLighter時(shí)的一些方面;文章分兩部分,第一部分是介紹如何在lucene中應(yīng)用Highlighter進(jìn)行高亮顯示而不影響到搜索速度。第二部分則是對(duì)一些高亮錯(cuò)誤現(xiàn)象進(jìn)行分析并給出解決方法,以及糾正對(duì)高亮錯(cuò)誤存在的認(rèn)識(shí)誤區(qū)。總之,這篇文章就是希望能徹底解決在lucene中應(yīng)用高亮顯示所遇到的一切問(wèn)題!另外淑珍分詞器也發(fā)布了新的版本ShuzhenAnalyzer-1.1.6,也給出了一個(gè)淑珍分詞器的演示地址


          第一部分:在lucene中應(yīng)用高亮顯示而不影響到搜索的速度

          淑珍分詞器寫(xiě)好后,我做了些測(cè)試,這其中就包括對(duì)搜索結(jié)果進(jìn)行命中的測(cè)試,當(dāng)時(shí)我就發(fā)現(xiàn)了一個(gè)問(wèn)題,那就是如果按照常規(guī)應(yīng)用方法,比如按照目前市面上流行的介紹lucene的書(shū)籍中介紹的高亮顯示方法,那搜索的速度就會(huì)降低,原因很簡(jiǎn)單,那是因?yàn)樵谶M(jìn)行高亮顯示的時(shí)候,又進(jìn)行了一次搜索,所以導(dǎo)致了搜索速度慢的問(wèn)題,當(dāng)時(shí)我對(duì)這個(gè)問(wèn)題并沒(méi)有深究,因?yàn)樵谄匠V形矣貌恢M(jìn)行高亮處理,但前段時(shí)間有個(gè)朋友給我反饋1.1.4版本中存在的一個(gè)bug時(shí),雖然這個(gè)bug與高亮無(wú)關(guān),但卻使我決定把1.1.4版本再完善一下,順便解決這個(gè)高亮問(wèn)題。

          對(duì)于這個(gè)問(wèn)題,我還是先搜索了一番,因?yàn)槲蚁肴绻麆e人已經(jīng)有很好的解決方法了,那我再自己費(fèi)神去想就很沒(méi)必要了,但搜索一番后,結(jié)果卻是令自己不甚滿意的,的確是有關(guān)于這方面的解決方法,但我覺(jué)得是并沒(méi)有說(shuō)得很清楚,首先這個(gè)思路應(yīng)該是這樣的:
          1、在索引創(chuàng)建的時(shí)候,應(yīng)當(dāng)記錄被索引的文字在被索引的內(nèi)容中的確切位置,這個(gè)位置就是文字的開(kāi)始位置和截止位置(比如“電腦”在內(nèi)容“我們用電腦可以做很多事情”中的位置,我們可以得知起始是3,結(jié)束位置是5)。
          2、然后在搜索得到結(jié)果的時(shí)候,應(yīng)當(dāng)將這些信息保存到內(nèi)存中,以便高亮的時(shí)候不用再次遍歷就可以很快地從內(nèi)存中得到。
          3、高亮的時(shí)候直接從內(nèi)存中得到要被高亮文字的位置信息。

          據(jù)說(shuō)是lucene從1.4.3版本開(kāi)始就支持在內(nèi)存中記錄搜索結(jié)果的位置信息了,依上處理為:

          1、創(chuàng)建索引時(shí):
          Field f = new Field("title",title,Field.Store.YES, Field.Index.TOKENIZED,Field.TermVector.WITH_POSITIONS_OFFSETS);

          在Field類中,有
          public static final TermVector WITH_POSITIONS_OFFSETS = new TermVector("WITH_POSITIONS_OFFSETS");
          注釋說(shuō)明是:Store the term vector + Token position and offset information,就是做這個(gè)事的
          常規(guī)的寫(xiě)法是沒(méi)有Field.TermVector.WITH_POSITIONS_OFFSETS這個(gè)參數(shù)的
          2、在HighlighterTest.java(你也可以新建一個(gè)類或改名,我是新建的一個(gè)類)中拷貝doStandardHighlights()的內(nèi)容新建一個(gè)方法,將以下的
          TokenStream tokenStream = analyzer.tokenStream(FIELD_NAME,new StringReader(text));
          改為:
           1         TokenStream tokenStream = null;       
           2         if (reader==null){
           3             reader = IndexReader.open(indexPath);
           4         }
           5         //docNumber是文檔ID,FIELD_NAME是索引字段
           6         TermPositionVector tpv = (TermPositionVector)reader.getTermFreqVector(docNumber,FIELD_NAME);
           7         //如果沒(méi)有stop words去除還可以改成 TokenSources.getTokenStream(tpv,true); 進(jìn)一步提速。
           8         if (tpv!=null){
           9             tokenStream=TokenSources.getTokenStream(tpv,true);
          10         }

          關(guān)于TermPositionVector類,不是必定全包含被搜索到的結(jié)果的位置和偏移位置,但至少會(huì)包含一項(xiàng),這是對(duì)英文的直譯,聽(tīng)來(lái)有點(diǎn)拗口,其實(shí)可以簡(jiǎn)單理解就是要得到結(jié)果的位置信息得找它!

          好了,在lucene中應(yīng)用高亮顯示而不影響到搜索的速度介紹完了,但是,這樣子高亮就一定正確嗎?在接下來(lái)的第二部分中我會(huì)說(shuō)明這還并不能百分百保證高亮正確,這也是我為什么考慮將兩部分合在一起講述的原因。

          第二部分:影響高亮顯示正確的因素

          因素1:所使用的分詞器不滿足分詞標(biāo)準(zhǔn)
          現(xiàn)在的淑珍分詞器最新版本是1.1.6,1.1.6與1.1.4版本相比較修正了兩個(gè)Bug(之間還有1.1.5版本,修正了一個(gè)Bug),而這兩個(gè)Bug都會(huì)導(dǎo)致在某種情況下高亮顯示不正確,雖然這種情況并不罕見(jiàn),甚至比Google的高亮顯示Bug還不常見(jiàn),但這畢竟是兩個(gè)Bug。我在上一篇博文中提到過(guò)分詞標(biāo)準(zhǔn)這個(gè)概念,我提到如果一個(gè)分詞器不符合分詞標(biāo)準(zhǔn),那么在與高亮器一起使用時(shí)會(huì)導(dǎo)致高亮錯(cuò)誤,這個(gè)提出也是基于我對(duì)分詞器原理的一種較為深刻的理解而得出的吧,如果說(shuō)上次提出的時(shí)候還只是很大可能推測(cè)的話,那么現(xiàn)在我卻是敢肯定這點(diǎn):那就是不滿足分詞標(biāo)準(zhǔn)的分詞器必定會(huì)導(dǎo)致高亮錯(cuò)誤。
          在修正淑珍分詞器這兩個(gè)Bug的過(guò)程中,我發(fā)現(xiàn)原因都是我在寫(xiě)的過(guò)程中有兩處地方?jīng)]有符合分詞標(biāo)準(zhǔn)的規(guī)范所導(dǎo)致的,而當(dāng)我使之符合分詞標(biāo)準(zhǔn)后,這兩個(gè)Bug也沒(méi)有了。
          我在網(wǎng)上看到有些文章在碰到高亮錯(cuò)誤的時(shí)候,沒(méi)有想到是分詞器的錯(cuò)誤,而是去修改HighLighter等高亮器,我想這是錯(cuò)誤的,這把一種原本正確的東西改錯(cuò)了,這也算是一種以訛傳訛吧,我希望我的這篇文章能糾正這種錯(cuò)誤的看法,不要讓這種以訛傳訛再繼續(xù)下去了。

          因素2:假設(shè)這個(gè)時(shí)候分詞器也符合了分詞標(biāo)準(zhǔn)的規(guī)范,但還有個(gè)情況我現(xiàn)在所發(fā)現(xiàn)會(huì)導(dǎo)致高亮錯(cuò)誤,那就是所使用的高亮CSS樣式,我碰到這種錯(cuò)誤的時(shí)候,剛開(kāi)始我以為是分詞器還有其他地方?jīng)]有符合分詞標(biāo)準(zhǔn)的規(guī)范,但后來(lái)我確證百分百我的分詞器沒(méi)有問(wèn)題了,而這個(gè)錯(cuò)誤還是顯示,這個(gè)時(shí)候我才意識(shí)到了是其他錯(cuò)誤,以下是我搜索關(guān)鍵詞“異界”,前后兩次所使用的代碼:
          顯示錯(cuò)誤的:
          SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<span class=\"style7\">","</span>");

          如圖:

          錯(cuò)誤地方:界<
          改后沒(méi)問(wèn)題的:
          SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<b>","</b>");

          (至于其他代碼可以參看HighlighterTest.java)
          如圖:

          當(dāng)然,這個(gè)錯(cuò)誤原因具體如何,我沒(méi)有深究,有興趣的同學(xué)可以去深入研究一下。。。



          淑珍分詞器ShuzhenAnalyzer-1.1.8下載地址見(jiàn)
          http://www.aygfsteel.com/Files/bbmonkey62/ShuzhenAnalyzer-1.1.8-jdk1.6.0.rar

          淑珍分詞器ShuzhenAnalyzer-1.1.7下載地址見(jiàn)
          For JDK1.6:
          http://www.aygfsteel.com/Files/bbmonkey62/ShuzhenAnalyzer-1.1.7-jdk1.6.0.rar
          For JDK1.5:
          http://www.aygfsteel.com/Files/bbmonkey62/ShuzhenAnalyzer-1.1.7-jdk1.5.0.rar

          關(guān)于分詞器的詳細(xì)介紹以及版本變更情況請(qǐng)參見(jiàn):
          http://www.shuzhen.net


          posted on 2009-04-17 00:49 bbmonkey62笨笨猴 閱讀(1882) 評(píng)論(3)  編輯  收藏

          評(píng)論

          # re: 解決在lucene中應(yīng)用高亮顯示所遇到的問(wèn)題及ShuzhenAnalyzer-1.1.6發(fā)布 2009-04-17 09:41 mrzhu
          麻煩問(wèn)一下,用Lucene為文件建立索引的時(shí)候,如果我的文件是word類型的,而且文件中包含圖片等非文本字符,Lucene只能對(duì)文本信息建立索引。查看詳細(xì)的時(shí)候所有的圖片都是亂碼 這應(yīng)該怎么解決啊 用POI讀取java也只能抽文本  回復(fù)  更多評(píng)論
            

          # re: 解決在lucene中應(yīng)用高亮顯示所遇到的問(wèn)題及ShuzhenAnalyzer-1.1.6發(fā)布 2009-04-17 14:54 bbmonkey62笨笨猴
          @mrzhu
          在建立索引時(shí),lucene是支持索引非文本數(shù)據(jù)的,我不知道你在索引的時(shí)候是怎么用的,但我建議你去看如下內(nèi)容:
          在org.apache.lucene.document.Field里的構(gòu)造方法:
          public Field(String name, byte[] value, Store store)
          請(qǐng)留意第二個(gè)參數(shù),在建立索引的時(shí)候允許非文本的字符,比如大文件類型轉(zhuǎn)換為byte[]型索引起來(lái),然后你取的時(shí)候再做相應(yīng)的轉(zhuǎn)換

          我沒(méi)做測(cè)試,你可以去測(cè)試下是否可行,我覺(jué)得是可以的。。。  回復(fù)  更多評(píng)論
            

          # re: 解決在lucene中應(yīng)用高亮顯示所遇到的問(wèn)題及ShuzhenAnalyzer-1.1.6發(fā)布 2009-04-17 17:38 bbmonkey62笨笨猴
          請(qǐng)?jiān)?009-04-17下午5點(diǎn)35分以前下過(guò)1.1.6版本的朋友們?cè)僦匦孪乱槐椋捎谖抑皽y(cè)試得不夠嚴(yán)密,5點(diǎn)35分以前的1.1.6版本在對(duì)搜索詞進(jìn)行處理(segmentKeyExact(key)和segmentKeyFuzzy(key))時(shí),當(dāng)搜索詞是某種組合的時(shí)候會(huì)導(dǎo)致比較嚴(yán)重的錯(cuò)誤,其他功能沒(méi)有發(fā)現(xiàn)問(wèn)題,非常抱歉,敬請(qǐng)諒解  回復(fù)  更多評(píng)論
            


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 神池县| 邢台县| 突泉县| 新乐市| 荥阳市| 鄂托克前旗| 延吉市| 和田市| 遵义市| 新乐市| 诏安县| 江西省| 太湖县| 易门县| 惠州市| 青铜峡市| 任丘市| 密云县| 台东市| 乌苏市| 哈巴河县| 通化县| 石嘴山市| 安乡县| 牡丹江市| 七台河市| 东乡| 东阿县| 长岭县| 海原县| 涡阳县| 广西| 宜宾市| 永兴县| 北安市| 遂平县| 乡宁县| 上饶县| 湖北省| 巴塘县| 孝义市|