5、IndexWriter
索引這部分最後講的是IndexWriter。如果說前面提到的都是資料的結構,那麼IndexWriter就是業務的封裝。無論述Document,Field還是看不見的Segment,Term都是對資料存儲邏輯的抽象,IndexWriter包裝了操作的過程。
當然,這裡不會讨論IndexWriter的每個細節,這裡主要介紹IndexWriter的常用法和實際使用中遇到的部署問題。
5.1 IndexWriter的常用方法
IndexWriter的用法很簡單,前文有例子。在《接觸Lucene.Net 》一文中代碼2.1.1就是最簡單的用法。可以看到IndexWriter的構造函數很重要,AddDocument方法也很重要,有這兩個方法,就可以建立索引了。其它的方法都是對建立索引的過程或者結果進行了優化,或者是提供了一些索引中或者索引後的資料。比如,常用的Optimize方法,就是對索引進行優化,使得搜尋能夠效率更高。還有一些常用的方法(按字母排序):
(1)、AddIndexes方法是合并不同部分索引的,這個方法很有用,比如,用5個線程在5個目錄下建立索引,然後用這個方法把5個索引合并為一個,這樣就能提高索引的效率;
(2)、Close方法是最後使用的方法,除了能夠去除對檔案的鎖定外,還能起到Flush方法的作用。這個方法非常重要,在IndexWriter執行個體建立後,無論出現什麼樣的問題,哪怕程式崩潰,都一定要顯式調用該方法。要不然索引會處于鎖定狀态,無法解除;
(3)、DeleteDocuments是用來删除索引的,這裡隻能指定Term删除,使用價值不是太高;
(4)、Flush方法是把緩沖資料寫入的一個方法,在不想關閉索引但是要清空緩沖區的時候使用;
(5)、Optimize方法是優化索引的方法,如果索引資料很大,則調用這個方法會耗費很長時間。另外就是,如果索引檔案這個時候被讀取,并不能達到删除廢棄檔案的目的。
(6)、SetMaxBufferedDocs方法是規定緩沖區能夠緩沖Document的個數,因為寫硬碟要比寫記憶體慢很多,這個值設定得越大,暫時存儲到記憶體的Document就會越多;
(7)、SetMaxFieldLength方法設定Field的最大長度;
(8)、UpdateDocument用來更新索引,但是實際上并不是真正的更新,而是先删除,再添加,如果不進行優化,那麼至少會增加兩個檔案,一個記錄了增加的一個記錄了删除的。
5.2 索引的部署
索引的部署根據索引的大小而趨向複雜,我認為至少是平方增長。複雜度增長的原因在于,索引大小的增長,将會引入更多需要考慮的因素。比如,索引的重建,索引優化時間,多索引部署等,而分布式部署基本上是目前最複雜的部署方案。
一般來說,應該一個索引存儲,隻應該由一個IndexWriter來控制。一個存儲不應該超過2G,即使是2G,每次索引更新都需要10分鐘左右來優化索引。至于如何配置設定索引,要根據實際情況來決定,而且要考慮諸如程式崩潰等情況。
在Java版的搜尋引擎解決方案中有很多可以借鑒的地方,比如,對于資料索引,Compass的索引方式可以參考;對于抓取式的搜尋引擎,Nutch可以參考;分布式解決方案可以參考Hadoop。如何實作像Compass一樣,添加、删除、更新都能及時反映到索引當中,站内搜尋引擎一般都會面臨這樣的問題。Lucene.Net已經為我們提供了實作的方法,至于實作的邏輯需要你去思考。
6、索引小節
本篇文章是索引部分的完結篇。從第一篇到這裡第七篇,主要介紹了兩個東西,一個是Lucene.Net的邏輯存儲,另外一個就是如何操作邏輯存儲。在邏輯存儲上講得比較詳細,特别是關于權重部分,而操作則隻簡單提一下。因為,邏輯存儲有助于了解Lucene.Net索引的流程,而操作則隻是相當于CPU的指令,業務邏輯需要自己去實作。相信看了以上七篇文章,有助于對Lucene.Net索引的了解,當然,這裡隻講了表面上的東西,更加深入地了解Lucene需要從更加底層的Directory入手。索引部分就暫時寫到這裡了,後面将進入搜尋問題的探讨。