2013-06-19 2 views
0

간단히 말해서, 하위 인덱스 판독기에 상대적인 문서 만 제공하는 CustomScoreProvider.CustomScore 메서드에서 문서의 실제 문서 ID를 확인하려고합니다.CustomScoreProvider에서 문서 ID를 얻는 방법은 무엇입니까?

추가 정보 : 미리 계산 된 부스트 요인 (Lucene의 문서 ID를 매핑하여 요소를 늘리는 메모리 내장 구조)을 생각해 내 문서의 점수를 높이려고합니다. 불행히도 필자는 몇 가지 이유로 인덱스에 boost를 저장할 수 없다. boosting은 모든 쿼리에 사용되지 않을 것이고, boost 요소가 정기적으로 바뀔 수 있고 많은 재 인덱스를 유발할 것이다.

대신 쿼리 시간에 점수를 높이고 싶습니다. 따라서 CustomScoreQuery/CustomScoreProvider로 작업하고 있습니다. 부스팅는 방법 CustomScoreProvider.CustomScore에서 일어난다 :

public override float CustomScore(int doc, float subQueryScore, float valSrcScore) { 
    float baseScore = subQueryScore * valSrcScore; // the default computation 
    // boost -- THIS IS WHERE THE PROBLEM IS  
    float boostedScore = baseScore * MyBoostCache.GetBoostForDocId(doc); 
    return boostedScore; 
} 

내 문제는 CustomScore에 전달 된 doc 매개 변수입니다. 실제 문서 ID가 아닙니다. 인덱스 세그먼트에 사용 된 하위 판독기와 관련이 있습니다. (MyBoostCache 클래스는 Lucene의 문서 ID를 매핑하는 내 메모리 구조입니다.) 독자의 docBase를 알면 참된 ID (id = doc + docBase)를 알 수있었습니다.

내가 진정한 이드를 어떻게 결정할 수 있을지 또는 내가하는 일을 성취 할 수있는 더 좋은 방법이 있을지 생각해보십시오.

(내가 얻으려고 ID가 변경 될 수 있음을 알고 나는 이미 MyBoostCache 최신 ID가 항상 최신 상태로 있는지 확인하기위한 조치를 촬영했습니다.)

답변

0

I이었다 IndexSearcher를 CustomScoreProvider에 전달하여 CustomScoreProvider에서 사용중인 서브 리더를 확인한 다음 IndexSearcher의 이전 서브 리더에 대해 MaxDoc을 가져 와서 docBase를 결정합니다.

private int DocBase { get; set; } 

public MyScoreProvider(IndexReader reader, IndexSearcher searcher) { 
    DocBase = GetDocBaseForIndexReader(reader, searcher); 
} 

private static int GetDocBaseForIndexReader(IndexReader reader, IndexSearcher searcher) { 
    // get all segment readers for the searcher 
    IndexReader rootReader = searcher.GetIndexReader(); 
    var subReaders = new List<IndexReader>(); 
    ReaderUtil.GatherSubReaders(subReaders, rootReader); 

    // sequentially loop through the subreaders until we find the specified reader, adjusting our offset along the way 
    int docBase = 0; 
    for (int i = 0; i < subReaders.Count; i++) 
    { 
     if (subReaders[i] == reader) 
      break; 
     docBase += subReaders[i].MaxDoc(); 
    } 

    return docBase; 
} 

public override float CustomScore(int doc, float subQueryScore, float valSrcScore) { 
    float baseScore = subQueryScore * valSrcScore; 
    float boostedScore = baseScore * MyBoostCache.GetBoostForDocId(doc + DocBase); 
    return boostedScore; 
} 
관련 문제