Lucene.net:排序时内存不足

时间:2012-03-04 08:50:52

标签: lucene.net

我有一个相当大的Lucene.net索引(使用最新版本创建 - 2.9)。它有大约10亿份文件。它需要约70GB的高清空间。每个文档都非常小,只有两个字段:字符串和整数。

我想通过字符串字段进行搜索,并按索引字段排序。问题是,当我尝试使用排序运行查询时,我得到一个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()的整数或float数组,用于为其执行排序的每个字段名称。换句话说,缓存的大小以字节为单位:   4 * IndexReader.maxDoc()*(实际用于排序的不同字段的数量)

我能以某种方式改变这种行为吗?

2 个答案:

答案 0 :(得分:1)

不,你不能改变这种行为。但由于您只对最高结果感兴趣,因此您可以编写自定义Collector并获得最高结果而不对整个结果集进行排序(例如在O(n)时间内查找整数数组中的最大值)< / p>

如果您对前n个结果感兴趣,可以使用PriorityQueue。以下是my another answer,其中显示了如何使用PriorityQueueCollector

答案 1 :(得分:1)

我最终做了一些与众不同的事情。意识到我总是希望我的结果以这种方式排序,我真正需要的是影响Scoring。我在使用Document.SetBoost()并使用整数参数值时重建了索引,因此每个文档的分数由该字段的值决定。由于默认的Lucene行为是返回最好的得分文档,我得到了我需要的东西。