2010-01-20 55 views
5

摘要:我通過使用自定義收集器(它使用ID填充BitSet)收集給定搜索的所有匹配的文檔ID。根據我的需要,搜索和獲取文檔ID相當快,但實際上從磁盤獲取文檔時,事情變得非常緩慢。有沒有辦法優化Lucene以加快文檔收集速度?收集在Lucene /優化中搜索的所有匹配

詳情:我正在處理維基百科的處理語料庫,並將每個句子作爲單獨的文檔保存。當我搜索「計算機」時,我會得到包含術語計算機的所有句子。目前,搜索語料庫並獲取所有文檔ID在亞秒內工作,但獲取前1000個文檔大約需要20秒。提取所有文檔需要比例更多的時間(即每個1000個文檔批次需要20秒)。

後續的搜索和文檔抓取花費的時間要少得多(儘管我不知道誰在做緩存,操作系統或Lucene?),但我會搜索許多不同的術語,我不想依靠緩存,首次搜索的性能對我至關重要。

我在尋找能夠提高文檔抓取性能的建議/技巧(如果可能的話)。提前致謝!

附錄

我利用Lucene 3.0.0,但我用的Jython驅動Lucene的類。這意味着,我叫下面的Jython類的get_doc方法我在搜索中檢索到的每個文檔ID:

class DocumentFetcher(): 
    def __init__(self, index_name): 
    self._directory = FSDirectory.open(java.io.File(index_name)) 
    self._index_reader = IndexReader.open(self._directory, True) 
    def get_doc(self, doc_id): 
    return self._index_reader.document(doc_id) 

我有50M的文件在我的索引。

+0

我已經使用了這種大小的數據,但沒有處理這些很多(50M)文檔。當您只檢索幾十個文檔時,20ms是一個「良好」的響應時間,這是典型情況。在這種情況下,因爲您想檢索大量數據,所以感覺太慢了。如果你想要更好的性能,我想,你需要使用大量的內存。 – 2010-01-25 09:42:58

+0

我假設內存速度的折衷會涉及某種預熱Lucene(在執行搜索和讀取操作之前將大量文檔加載到內存中)嗯,也許我可以將文檔保存在外部數據庫中並希望DB可以更好地管理緩存問題,然後我的自定義解決方案。 – 2010-01-25 10:23:44

+0

您可以對FieldCache.DEFAULT進行虛擬調用。getStrings()將加載該字段上的所有值。如果該呼叫能夠在OOME中生存下來,您將會看到我之前提供的解決方案的性能提升。 – 2010-01-25 16:44:25

回答

2

您可能正在文檔中存儲大量信息。儘可能減少存儲的字段。

其次,在檢索字段時,只選擇那些你需要的字段。您可以使用IndexReader的以下方法僅指定幾個存儲的字段。

public abstract Document document(int n, FieldSelector fieldSelector) 

這樣你就不會加載未使用的字段。

您可以使用以下代碼示例。

FieldSelector idFieldSelector = 
new SetBasedFieldSelector(Collections.singleton("idFieldName"), Collections.emptySet()); 
for (int i: resultDocIDs) { 
String id = reader.document(i, idFieldSelector).get("idFieldName"); 
} 
+0

感謝您的建議和代碼示例。我不知道FieldSelector,它可能在未來有用。 但是,我只在文檔中存儲了一個字段,這就是我最終要獲取的內容。我存儲的唯一字段僅僅是句子本身以及一些語法註釋。這意味着對於單個文檔(即句子),我不會存儲超過300-400個字節。 (附加信息:我已經索引了大約50M文檔) – 2010-01-20 12:37:14