0

つまり、サブ IndexReader に関連CustomScoreProvider.CustomScoreするドキュメント「ID」のみを提供するメソッドで、ドキュメントの真のドキュメント ID を判断しようとしています。

詳細情報: 事前に計算されたブースト ファクターによってドキュメントのスコアをブーストしようとしています (Lucene のドキュメント ID をブースト ファクターにマップするメモリ内構造を想像してください)。残念ながら、いくつかの理由でブーストをインデックスに保存することはできません。ブーストはすべてのクエリに使用されるわけではありません。さらに、ブースト係数は定期的に変更される可能性があり、多くの再インデックス作成を引き起こす可能性があります。

代わりに、クエリ時にスコアを上げたいので、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;
}

私の問題は、docCustomScore に渡されるパラメーターにあります。これは実際のドキュメント ID ではありません。そのインデックス セグメントに使用されるサブリーダーに関連しています。(このMyBoostCacheクラスは、Lucene のドキュメント ID をブースト ファクターにマッピングするメモリ内構造体です。) リーダーの docBase を知っていれば、本当の ID ( id = doc + docBase) を知ることができます。

真のIDを特定する方法について何か考えがありますか、それとも私がやっていることを達成するためのより良い方法がありますか?

(私が取得しようとしている ID は変更される可能性があることを認識しておりMyBoostCache、最新の ID で常に最新であることを確認するための措置を既に講じています。)

4

1 に答える 1

0

IndexSearcher を CustomScoreProvider に渡し、それを使用して CustomScoreProvider によって使用されているサブMaxDocリーダーを特定し、IndexSearcher から以前のサブリーダーの を取得して 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;
}
于 2013-06-21T02:13:49.263 に答える