2012-03-04 26 views
1

我有一個相當大的Lucene.net索引(使用最新版本創建 - 2.9)。它有大約10億份文件。它需要~70GB的高清空間。每個文檔都非常小,只有兩個字段:一個字符串和一個整數。Lucene.net:排序時內存不足

我想按字符串字段搜索,並按索引字段排序。問題是,當我嘗試使用排序運行查詢時,出現OutOfMemoryException。該代碼看起來是這樣的:

var sort = new Sort(new SortField("frequency",SortField.INT,false)); 
var topDocs = searcher.Search(query, null, 1,sort); 

不要緊,我使用的查詢,如果我使用的排序,它崩潰。這裏是堆棧跟蹤:

System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown. 
at Lucene.Net.Search.FieldCacheImpl.IntCache.CreateValue(IndexReader reader, Entry entryKey) 
at Lucene.Net.Search.FieldCacheImpl.Cache.Get(IndexReader reader, Entry key) 
at Lucene.Net.Search.FieldCacheImpl.GetInts(IndexReader reader, String field, IntParser parser) 
at Lucene.Net.Search.FieldCacheImpl.IntCache.CreateValue(IndexReader reader, Entry entryKey) 
at Lucene.Net.Search.FieldCacheImpl.Cache.Get(IndexReader reader, Entry key) 
at Lucene.Net.Search.FieldCacheImpl.GetInts(IndexReader reader, String field, IntParser parser) 
at Lucene.Net.Search.FieldComparator.IntComparator.SetNextReader(IndexReader reader, Int32 docBase) 
at Lucene.Net.Search.IndexSearcher.Search(Weight weight, Filter filter, Collector collector) 
at Lucene.Net.Search.IndexSearcher.Search(Weight weight, Filter filter, Int32 nDocs, Sort sort, Boolean fillFields) 
at Lucene.Net.Search.IndexSearcher.Search(Weight weight, Filter filter, Int32 nDocs, Sort sort) 
at Lucene.Net.Search.Searcher.Search(Query query, Filter filter, Int32 n, Sort sort) 

我對Lucene來說還是比較新的。看起來它試圖緩存大量數據並耗盡內存。

更新: 事實上,看起來像Lucene試圖創建一個數組int [maxDoc],這是一個巨大的,如果我的情況。

排序使用內部HitQueue維護的期限值的高速緩存。緩存是靜態的,並且包含一個長度爲IndexReader.maxDoc()的整數或浮點數組,用於執行排序的每個字段名稱。換句話說,緩存的字節大小爲: 4 * IndexReader.maxDoc()*(不同領域的實際#用於排序)

我可以以某種方式改變這種行爲?

回答

1

我最終做了一些不同的事情。意識到我總是希望以這種方式排序我的結果,我真正需要的是影響Scoring。我使用整數參數的值Document.SetBoost()重建了我的索引,因此每個文檔的得分由該字段的值決定。由於默認的Lucene行爲是返回最好的評分文檔,我得到了我所需要的。

1

不,你不能改變這種行爲。但是,由於您只對最高結果感興趣,因此您可以編寫自定義Collector並獲得最高結果,而無需對整個結果集進行排序(如在O(n)時間內查找整數數組中的最大值)

如果您對top-n結果感興趣,那麼您可以使用PriorityQueue。這裏是my another answer顯示如何使用PriorityQueueCollector