Lucene中建立索引的效率和刪除索引的實現

gorillamax發表於2009-04-28

越來越多的人利用開源元件 Lucene來開發自己的搜尋引擎。在資料量不大的情況下,我們不會太關注建立索引的效率;但是,但資料達到一定的數量是,我們就不得不考慮如何提高建立索引的效能,以縮短索引建立的時間。

[@more@]

我們是用Lucene中提供的類IndexWriter來建立索引的,所以我們不妨先看一看IndexWriter類中關係到索引建立效率的幾個方法。

一、SetMergeFactor(合併因子)
SetMergeFactor是控制segment合併頻率的,其決定了一個索引塊中包括多少個文件,當硬碟上的索引塊達到多少時,將它們合併成一個較大的索引塊。當MergeFactor值較大時,生成索引的速度較快。MergeFactor的預設值是10,建議在建立索引前將其設定的大一些。

二、SetMaxBufferedDocs(最大快取文件數)

SetMaxBufferedDocs是控制寫入一個新的segment前記憶體中儲存的document的數目,設定較大的數目可以加快建索引速度,預設為10。

三、SetMaxMergeDocs(最大合併文件數)
SetMaxMergeDocs是控制一個segment中可以儲存的最大document數目,值較小有利於追加索引的速度,預設Integer.MAX_VALUE,無需修改。

在建立大量資料的索引時,我們會發現索引過程的瓶頸在於大量的磁碟操作,如果記憶體足夠大的話,我們應當儘量使用記憶體,而非硬碟。可以透過SetMaxBufferedDocs來調整,增大Lucene使用記憶體的次數。

如果記憶體足夠大的話,我們也可以在索引過程中完全避免使用硬碟。Lucene支援使用檔案系統和記憶體兩種方式建立索引,我們可以先把索引寫入到RAMDirectory,達到一定數量時再批次寫進FSDirectory,減少磁碟操作次數。相關的程式碼如下:

RAMDirectory rmd = new RAMDirectory();IndexWriter writer = new IndexWriter(rmd, new StandardAnalyzer(), true);while (not eof) //遍歷{
Document doc = new Document();doc.Add(); //Add Fieldswriter.AddDocument(doc);}writer.SetUseCompoundFile(true);writer.Optimize();writer.Close();

另外,SetUseCompoundFile這個方法可以使Lucene在建立索引庫時,會合並多個 Segments 檔案到一個 .cfs 中。此方式有助於減少索引檔案數量,對於將來搜尋的效率有較大影響。

若需要從索引中刪除某一個或者某一類文件,IndexReader提供了兩種方法:
reader.DeleteDocument(int docNum)
reader.DeleteDocuments(Term term)

前者是根據文件的編號來刪除該文件,docNum是該文件進入索引時Lucene的編號,是按照順序編的;後者是刪除滿足某一個條件的多個文件。

在執行了DeleteDocument或者DeleteDocuments方法後,系統會生成一個*.del的檔案,該檔案中記錄了刪除的文件,但並未從物理上刪除這些文件。此時,這些文件是受保護的,當使用Document doc = reader.Document(i)來訪問這些受保護的文件時,Lucene會報“Attempt to access a deleted document”異常。如果一次需要刪除多個文件時,可以用兩種方法來解決:

1. 刪除一個文件後,用IndexWriter的Optimize方法來最佳化索引,這樣我們就可以繼續刪除另一個文件。

2. 先掃描整個索引檔案,記錄下需要刪除的文件在索引中的編號。然後,一次性呼叫DeleteDocument刪除這些文件,再呼叫IndexWriter的Optimize方法來最佳化索引。

本文來自:

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/314122/viewspace-1021407/,如需轉載,請註明出處,否則將追究法律責任。

相關文章