2011-01-21 42 views
3

在Lucene中有幾個重載的IndexSearcher.Search方法。其中一些需要「top n hits」參數,有些則不會(這些過時並且會在Lucene.NET 3.0中刪除)。如何在不指示「top n」命中限制的情況下搜索Lucene.NET?

那些需要「top n」參數的參數實際上會導致內存預分配給整個可能的結果範圍。因此,當您處於無法近似估計返回結果數量的情況時,唯一的機會就是傳遞一個隨機數,以確保返回所有查詢結果。這會由於LOH碎片導致嚴重的記憶壓力和泄漏。

有沒有過時的方式來搜索沒有傳遞「top n」的論點?

在此先感謝,夥計們。

回答

2

我正在使用Lucene.NET 2.9.2作爲這個答案的參考點。

您可以構建一個自定義收集器,將其傳遞給其中一個搜索重載。

using System; 
using System.Collections.Generic; 
using Lucene.Net.Index; 
using Lucene.Net.Search; 

public class AwesomeCollector : Collector { 
    private readonly List<Int32> _docIds = new List<Int32>(); 
    private Scorer _scorer; 
    private Int32 _docBase; 

    public IEnumerable<Int32> DocumentIds { 
     get { return _docIds; } 
    } 

    public override void SetScorer(Scorer scorer) { 
     _scorer = scorer; 
    } 

    public override void Collect(Int32 doc) { 
     var score = _scorer.Score(); 
     if (_lowerInclusiveScore <= score) 
      _docIds.Add(_docBase + doc); 
    } 

    public override void SetNextReader(IndexReader reader, Int32 docBase) { 
     _docBase = docBase; 
    } 

    public override bool AcceptsDocsOutOfOrder() { 
     return true; 
    } 
} 
+0

謝謝您的建議。實際上,我們使用收集器的方式與使用LinkedList而不是List的唯一區別幾乎相同,以防止增長時對內存重新分配。這種方法在沒有必要進行分類時效果很好。沒有Search()超載接收Collector和Sort對象。當使用Sort時,我們強制Lucene使用默認的TopHitsCollector,它以一種描述的方式預分配內存。也許這是一個好主意,使用自定義收集器,這是它自己對Coolect調用進行排序。你怎麼看? – 2011-01-21 13:34:26

相關問題