笨笨的思想片斷

          零碎片斷,雜七雜八。
          posts - 25, comments - 79, trackbacks - 0, articles - 0

          中文全文檢索的實現(xiàn)以及一些經(jīng)驗(Java)

          Posted on 2007-07-30 17:55 笨笨 閱讀(5403) 評論(10)  編輯  收藏 所屬分類: Java

          中文全文檢索的實現(xiàn)以及一些經(jīng)驗(Java)


          最近在項目中面臨中文全文檢索的需求,關(guān)鍵需求如下:

          1 支持中文、英文字詞的全文檢索,待檢索文本是古文言文。
          2 全文檢索表達式支持: AND,OR,NOT,NEAR,BEFORE 運算符,支持()。
          3 速度要求:400M文本,要求在2-5秒內(nèi)能夠檢索完畢。



          嘗試Lucene以及放棄原因:

          在嘗試Lucene和不同的中文Analyzer后,終告放棄。
          原因如下:
          由于待檢索文本是古文,中文分詞技術(shù)無法派上用場。在將分隔存儲每個漢字后,發(fā)現(xiàn)從Lucene中檢索到的文本遠遠少于關(guān)鍵字實際匹配的文本,這一問題對于較長的檢索關(guān)鍵字尤其明顯。
          因為對于檢索準(zhǔn)確程度要求很高,故此放棄,但是Lucene出的這個問題的原因尚不清楚,希望能夠有人提出解答。



          自行實現(xiàn)中文全文檢索原理以及方法:

          1 構(gòu)建過程,忽略標(biāo)點符號,自行計算每個漢字在每個文本文件中的偏移量,并保存。
          2 檢索過程,定位每個漢字的偏移量,如果檢索表達式中每個漢字的預(yù)期偏移量與實際偏移量吻合,則匹配成功。
          3 采用 MappedByteBuffer 加快檢索速度,采用二分查找加快偏移量匹配速度,3個左右的關(guān)鍵字復(fù)合檢索能夠在1秒內(nèi)完成匹配(要求操作系統(tǒng)有足夠大的緩存)。


          目前實現(xiàn)的一些局限和優(yōu)勢:

          0 中文檢索速度足夠,準(zhǔn)確度比Lucene高(如果有高手能夠解決這個問題,我會很高興的廢棄掉這些類的)
          1 合適于中文,不適用英文文本
          2 全文檢索索引文件與原始文本文件的大小大約為2:3-3:4之間,300M大小,比Lucene大約多30M。
          3 索引文件的構(gòu)建時間長,400M大約需要3小時,同時由于如果任何文本文件更新,都需要重新構(gòu)建索引文件,
          因此不合適要經(jīng)常變化的文本索引。




          全文檢索代碼示例(TestFullTextQuery.java):
          File storeDir = new File("C:\\temp\\fulltext\\index");
          StoreSearcher searcher = new StoreSearcher(storeDir);
          String str = "大?藏 & 阿難"; //同時出現(xiàn) "大?藏" 和 "阿難", ?代表任意字符
          searcher.queryBegin(str, true);
          while(true){
              StoreSearcherResult ssr = searcher.getNextQueryResult();
              if ( ssr == null ){
                  break;
              }
              System.out.println("ID "+ssr.docId+":"+ssr.matchedCount);
          }
          searcher.queryEnd();
          searcher.close();

          運行結(jié)果
          ID T01n0001.TXT:320
          ID T01n0002.TXT:3
          ID T01n0004.TXT:2
          ID T01n0005.TXT:202
          ID T01n0006.TXT:131
          ....



          附:全文檢索表達式舉例

          關(guān)鍵字中間可以出現(xiàn)?,表明匹配任意字符。

          運算符名稱:運算符字符
          AND:&
          OR:,
          BEFORE:*
          NEAR:+
          NOT:-

          表達式舉例:
          (KEY1 <AND|OR|BEFORE|NEAR> KEY2) & (NOT KEY3)
          KEY1 KEY2 (關(guān)鍵字之間無運算符假設(shè)為AND)



          附:全文檢索文件格式信息

          DocInfoStore(文檔信息)
          --HEAD--
          DocCount:Integer                    文檔數(shù)目
          --DOC HEAD(PER DOC)--
          DocSeq:    Integer                        文檔順序號,內(nèi)部使用
          DocId:     Char[128]                    文檔唯一ID,字符串格式
          DocSepOfs: Integer                文檔分隔符數(shù)組的Ofs
          --DOC SEP OFS(PER DOC)--
          DocOfs:    ArrayOfInteger        文檔分隔數(shù)組


          WordInfoStore(每個漢字信息)
          --HEAD--
          WordCount:Integer                    漢字數(shù)
          --WORD IDX(Per Word)--
          WordChar:Integer                    漢字的Unicode值
          WordInfoOfs:Integer                漢字信息在文件中的偏移量
          WordInfoSize:Integer            漢字信息大小
          --WORD INFO(Per Word)--
          DocCount:                                    漢字出現(xiàn)的文檔數(shù)
          DocSeq(Per Doc):                  每個文檔的順序號
          WordInDocs:ArrayOfInteger 每個文檔中出現(xiàn)的漢字的偏移數(shù)組,從小到大排列


          源文件及CLASS下載地址:
          http://www.aygfsteel.com/Files/zhugf000/foreader2_ftsearch.zip

          Feedback

          # re: 中文全文檢索的實現(xiàn)以及一些經(jīng)驗(Java)  回復(fù)  更多評論   

          2007-07-31 08:52 by BruceLuo
          看一下。。。。。。

          # re: 中文全文檢索的實現(xiàn)以及一些經(jīng)驗(Java)  回復(fù)  更多評論   

          2007-07-31 10:33 by princegsc
          用正則表達式啊

          # re: 中文全文檢索的實現(xiàn)以及一些經(jīng)驗(Java)[未登錄]  回復(fù)  更多評論   

          2007-07-31 10:59 by 劉明
          說起來,Lucene的性能似乎不行啊(我沒測試過啊,只是網(wǎng)上資料說明)。似乎千萬級別就比較慢了。前段日子用Lucene開發(fā)了個站內(nèi)搜索(數(shù)據(jù)量大概在幾百萬吧),感覺無論是搜索(其實還好,在可接收范圍內(nèi))和索引都有點慢。有沒更好的實現(xiàn)啊?那些真正的能承受較大壓力的搜索都是怎么開發(fā)的?誰知道?

          # re: 中文全文檢索的實現(xiàn)以及一些經(jīng)驗(Java)  回復(fù)  更多評論   

          2007-07-31 14:59 by BruceLuo
          都是的分布式的,索引和爬取基本上都是用的C++,WEB層用的是PHP,這是完美的結(jié)合!

          # re: 中文全文檢索的實現(xiàn)以及一些經(jīng)驗(Java)  回復(fù)  更多評論   

          2007-07-31 17:08 by sitinspring
          這個有技術(shù)含量.

          # re: 中文全文檢索的實現(xiàn)以及一些經(jīng)驗(Java)[未登錄]  回復(fù)  更多評論   

          2007-08-01 14:12 by 劉明
          笨笨啊,我有點迷茫。能給解答一下嗎?

          公司的站內(nèi)搜索OK了,但領(lǐng)導(dǎo)讓我繼續(xù)研究研究搜索,但我不知道該繼續(xù)去研究什么好了。
          中文分詞?目前使用的模塊(JE)還可以,如果自己研發(fā)需要不少時間,還有詞庫問題。
          爬蟲?我們是站內(nèi)搜索,雖然頭說站外也是個方向,但很不明確,我對沒有明確需求的東西實在不感興趣。
          分布式?目前的量還沒必要(幾百萬),差的很遠的,而且如果一直站內(nèi)搜索的話也很難用上。
          緩沖?這個很有用,但目前實在沒有太好的想法。

          目前站內(nèi)搜索的狀況就是正常運行,沒什么錯誤,也不知道該改些什么。很迷茫。(還有個項目相反,能正常運行,但我還有很多想法,但領(lǐng)導(dǎo)說我在那個項目浪費太多時間了,不許我再做了,能運行就行。-_-!)

          最近很怪,我對搜索的研究很迷茫,對用戶的需求倒是很感興趣。我一直在思考自己的東西最終能給用戶帶來什么,如何讓用戶更加方便的使用。

          嗯。。。就是很迷茫,有啥好的建議嗎?

          # re: 中文全文檢索的實現(xiàn)以及一些經(jīng)驗(Java)  回復(fù)  更多評論   

          2007-08-02 14:04 by active1001
          用lucene檢索的時候,結(jié)果少的原因,應(yīng)該是,你查詢的時候用的分詞器不對。
          在查詢之前先把每個字直接加一個空格。例如:“中文檢索”-》“中 文 檢 索”。

          # re: 中文全文檢索的實現(xiàn)以及一些經(jīng)驗(Java)  回復(fù)  更多評論   

          2008-06-18 15:40 by litao
          很好的東西啊 呵呵 可惜缺少些jar

          能不能送我啊 litao1258@126.com

          多謝

          # re: 中文全文檢索的實現(xiàn)以及一些經(jīng)驗(Java)  回復(fù)  更多評論   

          2008-07-01 15:12 by litao
          東西已經(jīng)收到,不勝感激!

          # re: 中文全文檢索的實現(xiàn)以及一些經(jīng)驗(Java)  回復(fù)  更多評論   

          2008-08-11 11:46 by 小雨轉(zhuǎn)晴
          你好,笨笨,我剛剛研究lucene,現(xiàn)在面臨的問題也是中文的全文檢索,
          我的問題正好和你相反,我返回的數(shù)據(jù)太多了。
          比如搜索的keyword是[高考]會被拆分為[高][考]兩個字進行檢索。
          這樣的話檢索大量數(shù)據(jù)的時候就會很慢,而且我做了關(guān)鍵字的高亮顯示
          這樣一來,比如標(biāo)題為【2008年北京考區(qū)高考狀元】那么被高亮后為
          2008年北京[考]區(qū)[高][考]狀元,這樣看起來很不好,怎么樣可以按著【詞】來
          建立索引呢,然后按著【詞】進行檢索并高亮,頭疼的問題,可以和您討論一下嘛?
          其他的朋友也歡迎討論。希望您能聯(lián)系我一下,QQ396615834 MSN wind_1121@hotmail.com 十分感謝。
          主站蜘蛛池模板: 泽普县| 行唐县| 泽库县| 霞浦县| 密山市| 眉山市| 永德县| 类乌齐县| 宁波市| 西峡县| 大港区| 禄劝| 千阳县| 绥宁县| 唐山市| 九寨沟县| 涟水县| 红桥区| 赣榆县| 库车县| 望奎县| 翁源县| 广南县| 涿州市| 濮阳市| 江口县| 克什克腾旗| 漳浦县| 十堰市| 治多县| 库尔勒市| 宁化县| 祁门县| 明溪县| 福安市| 右玉县| 康马县| 祁阳县| 盈江县| 横峰县| 壶关县|