0

简而言之,我试图在CustomScoreProvider.CustomScore仅提供相对于 sub-IndexReader的文档“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;
}

我的问题是doc传递给 CustomScore 的参数。它不是真正的文档 ID——它与用于该索引段的子阅读器相关。(MyBoostCache该类是我将 Lucene 的 doc id 映射到提升因子的内存结构。)如果我知道读者的 docBase,我可以找出真正的 id ( id = doc + docBase)。

关于如何确定真实身份的任何想法,或者也许有更好的方法来完成我正在做的事情?

(我知道我想要获取的 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 回答