在Lucene中,查询可以由许多子查询组成。 (例如TermQuery对象)
我想要一种迭代搜索返回的文档的方法,然后对每个文档迭代子查询。
对于每个子查询,我想得到它匹配的次数。 (我也对fieldNorm等感兴趣)
我可以通过使用indexSearcher.explain来访问该数据,但这感觉非常hacky因为我需要解析每个嵌套的Interpre对象的“description”成员以尝试查找术语频率等。 ,称“解释”非常缓慢,所以我希望有更快的方法)
这里的背景是我想尝试对Lucene的前N个搜索结果进行重新排名,为此,尽可能多地提取匹配的“功能”显然很有帮助。
通过查看类似TermQuery的类的源代码,以下似乎是一种基本方法:
// For each document... (scoreDoc.doc is an integer)
Weight weight = weightCache.get(query);
if (weight == null)
{
weight = query.createWeight(indexSearcher, true);
weightCache.put(query, weight);
}
IndexReaderContext context = indexReader.getContext();
List<LeafReaderContext> leafContexts = context.leaves();
int n = ReaderUtil.subIndex(scoreDoc.doc, leafContexts);
LeafReaderContext leafReaderContext = leafContexts.get(n);
Scorer scorer = weight.scorer(leafReaderContext);
int deBasedDoc = scoreDoc.doc - leafReaderContext.docBase;
int thisDoc = scorer.iterator().advance(deBasedDoc);
float freq = 0;
if (thisDoc == deBasedDoc)
{
freq = scorer.freq();
}
'weightCache'是Map类型,非常有用,因此您不必为您处理的每个文档重新创建Weight对象。 (否则,代码运行速度大约慢10倍)
这大概是我应该做的吗?有没有明显的方法可以让它更快地运行? (对于280个文档,大约需要2毫秒,而执行查询本身需要大约1毫秒)
这种方法的另一个挑战是它需要代码来浏览Query对象以尝试查找子查询。例如,如果它是一个BooleanQuery,则调用query.clauses()并对它们进行递归以查找所有叶子的TermQuery对象,等等。不确定是否有更优雅/更不易碎的方法。