bbmonkey62笨笨猴

          中文分詞

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            2 隨筆 :: 0 文章 :: 38 評論 :: 0 Trackbacks

          ShuzhenAnalyzer-1.1.8與上一版本1.1.7在功能上沒有任何區別,版本的升級是為了能夠與lucene1.1.8一起使用。

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


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

          淑珍分詞器寫好后,我做了些測試,這其中就包括對搜索結果進行命中的測試,當時我就發現了一個問題,那就是如果按照常規應用方法,比如按照目前市面上流行的介紹lucene的書籍中介紹的高亮顯示方法,那搜索的速度就會降低,原因很簡單,那是因為在進行高亮顯示的時候,又進行了一次搜索,所以導致了搜索速度慢的問題,當時我對這個問題并沒有深究,因為在平常中我用不著進行高亮處理,但前段時間有個朋友給我反饋1.1.4版本中存在的一個bug時,雖然這個bug與高亮無關,但卻使我決定把1.1.4版本再完善一下,順便解決這個高亮問題。

          對于這個問題,我還是先搜索了一番,因為我想如果別人已經有很好的解決方法了,那我再自己費神去想就很沒必要了,但搜索一番后,結果卻是令自己不甚滿意的,的確是有關于這方面的解決方法,但我覺得是并沒有說得很清楚,首先這個思路應該是這樣的:
          1、在索引創建的時候,應當記錄被索引的文字在被索引的內容中的確切位置,這個位置就是文字的開始位置和截止位置(比如“電腦”在內容“我們用電腦可以做很多事情”中的位置,我們可以得知起始是3,結束位置是5)。
          2、然后在搜索得到結果的時候,應當將這些信息保存到內存中,以便高亮的時候不用再次遍歷就可以很快地從內存中得到。
          3、高亮的時候直接從內存中得到要被高亮文字的位置信息。

          據說是lucene從1.4.3版本開始就支持在內存中記錄搜索結果的位置信息了,依上處理為:

          1、創建索引時:
          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");
          注釋說明是:Store the term vector + Token position and offset information,就是做這個事的
          常規的寫法是沒有Field.TermVector.WITH_POSITIONS_OFFSETS這個參數的
          2、在HighlighterTest.java(你也可以新建一個類或改名,我是新建的一個類)中拷貝doStandardHighlights()的內容新建一個方法,將以下的
          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         //如果沒有stop words去除還可以改成 TokenSources.getTokenStream(tpv,true); 進一步提速。
           8         if (tpv!=null){
           9             tokenStream=TokenSources.getTokenStream(tpv,true);
          10         }

          關于TermPositionVector類,不是必定全包含被搜索到的結果的位置和偏移位置,但至少會包含一項,這是對英文的直譯,聽來有點拗口,其實可以簡單理解就是要得到結果的位置信息得找它!

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

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

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

          因素2:假設這個時候分詞器也符合了分詞標準的規范,但還有個情況我現在所發現會導致高亮錯誤,那就是所使用的高亮CSS樣式,我碰到這種錯誤的時候,剛開始我以為是分詞器還有其他地方沒有符合分詞標準的規范,但后來我確證百分百我的分詞器沒有問題了,而這個錯誤還是顯示,這個時候我才意識到了是其他錯誤,以下是我搜索關鍵詞“異界”,前后兩次所使用的代碼:
          顯示錯誤的:
          SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<span class=\"style7\">","</span>");

          如圖:

          錯誤地方:界<
          改后沒問題的:
          SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<b>","</b>");

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

          當然,這個錯誤原因具體如何,我沒有深究,有興趣的同學可以去深入研究一下。。。



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

          淑珍分詞器ShuzhenAnalyzer-1.1.7下載地址見
          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

          關于分詞器的詳細介紹以及版本變更情況請參見:
          http://www.shuzhen.net


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

          評論

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

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

          我沒做測試,你可以去測試下是否可行,我覺得是可以的。。。  回復  更多評論
            

          # re: 解決在lucene中應用高亮顯示所遇到的問題及ShuzhenAnalyzer-1.1.6發布 2009-04-17 17:38 bbmonkey62笨笨猴
          請在2009-04-17下午5點35分以前下過1.1.6版本的朋友們再重新下一遍,由于我之前測試得不夠嚴密,5點35分以前的1.1.6版本在對搜索詞進行處理(segmentKeyExact(key)和segmentKeyFuzzy(key))時,當搜索詞是某種組合的時候會導致比較嚴重的錯誤,其他功能沒有發現問題,非常抱歉,敬請諒解  回復  更多評論
            


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 宝清县| 阿尔山市| 准格尔旗| 九江县| 平湖市| 台湾省| 文成县| 桐柏县| 潞西市| 于田县| 长丰县| 黄石市| 离岛区| 永靖县| 林周县| 双牌县| 霸州市| 千阳县| 清远市| 九龙县| 长葛市| 辽宁省| 岢岚县| 册亨县| 抚州市| 噶尔县| 巨野县| 治县。| 原平市| 梅州市| 开鲁县| 玉门市| 苏尼特左旗| 新竹市| 和林格尔县| 大冶市| 仙桃市| 江口县| 昌都县| 班戈县| 三原县|