2011-01-21 5 views
3

Lucene에는 IndexSearcher.Search 메서드가 여러 번 오버로드됩니다. 그들 중 일부는 "상위 n 히트"인수가 필요하고 일부는 그렇지 않습니다 (이들은 쓸모 없으며 Lucene.NET 3.0에서 제거됩니다)."top n"조회수 제한없이 Lucene.NET을 검색하는 방법은 무엇입니까?

"상위 n"인수를 필요로하는 것들은 실제로이 전체 가능한 범위의 결과에 대해 메모리 사전 할당을 유발합니다. 따라서 반환 된 결과의 개수를 대략적으로 추정 할 수없는 상황에 처한 경우 유일한 기회는 임의의 큰 숫자를 전달하여 모든 쿼리 결과가 반환되도록하는 것입니다. 이로 인해 LOH 단편화로 인해 심각한 메모리 압박과 누수가 발생합니다.

"상위 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

의견을 보내 주셔서 감사합니다. 실제로 List에서 LinkedList를 사용하여 성장에 대한 메모리 재 할당을 막는 유일한 차이점과 거의 같은 방식으로 Collector를 사용했습니다. 이 방법은 정렬 작업이 필요없는 경우에 효과적입니다. 수집기 및 정렬 객체를 모두받는 Search() 오버로드가 없습니다. Sort를 사용할 때 Lucene이 기본 TopHitsCollector를 사용하도록 강제합니다.이 기본 TopHitsCollector는 설명 된 방식으로 메모리를 미리 할당합니다. 어쩌면 커스텀 콜렉터를 사용하는 것이 좋을 것이다. Coolect 콜에서 자체 정렬을하는 것이다. 어떻게 생각해? –

+0

나는 문서 ID와 목록 내의 정렬 값을 모두 저장하도록 변경하고 모든 결과가 수집되면 정렬을 수행합니다. 단일 키워드 필드가 정렬 필드로 사용되면 세그먼트 당 필드 값을로드하고 캐시 할 때 FieldCache를 사용할 수 있습니다. 캐시가 제대로 작동하려면 내부 판독기 (SetNextReader에서 전달 된 내부 판독기)를 사용해야합니다. – sisve

+0

예, 이것이 Field cache를 사용하는 것을 제외하고는 최선의 방법이라고 생각합니다. 이 것은 큰 인덱스에서 많은 메모리를 먹고 아주 자주 다시 열어야하기 때문에 몇 백 개의 행을 정렬하기 위해 모든 필드 데이터를 인덱스에서 메모리로로드하지 않는 것이 좋습니다. 그래서 귀하의 충고는 기본적으로 내 질문에 대한 대답 인 것 같습니다. Simon에게 감사드립니다. –

관련 문제