将 Lucene HitCollector (2.x) 迁移到 Collector (3.x)

D.O*_*nos 2 lucene

在我们的一个项目中,我们使用旧的 Lucene 版本 (2.3.2)。我现在正在查看当前的 Lucene 版本 (3.5.0) 并尝试重新编写旧代码。在旧项目中,我们扩展了 TopFieldDocCollector 以在 collect() 方法中做一些额外的过滤。然而,我在理解新的 Collector 类时遇到了一些麻烦,而且我找不到一个很好的例子。

1) 方法 setScorer()。我如何/从哪里获得 Scorer 对象?

2) 方法collect()。我想我需要创建自己的集合并存储我感兴趣的 docIds,对吗?

3)当扩展 TopDocsCollector 时,我需要实现一个 PriorityQueue 以在构造函数中使用,对吗?似乎没有标准的实现。但是我仍然需要我自己的 Collection 来存储 docIds(或者更确切地说,ScoreDocs),并在搜索完成后调用 populateResults?

总的来说,扩展 Collector 似乎比扩展 TopDocsCollector 容易(很多),但也许我遗漏了一些东西。

Rob*_*uir 5

  1. setScorer() 是一个钩子,Scorer 在实际进行搜索时由 IndexSearcher 传入。因此,如果您根本不关心分数,则基本上可以覆盖此方法(例如,将传入的 Scorer 保存下来以便您可以使用它)。从它的javadocs:

    在连续调用 {@link #collect(int)} 之前调用。需要当前文档分数的实现(传入 {@link #collect(int)}),应保存传入的 Scorer 并在需要时调用 scorer.score()。

  2. collect() 为每个匹配的文档调用,传入每个段的 docid。请注意,如果您需要“重新定位的 docid”(相对于其所有段中的整个阅读器),那么您必须覆盖 setNextReader,保存 docBase,并计算 docBase + docid。来自收集器 javadocs:

    注意:传递给 collect 方法的文档是相对于当前读者的。如果您的收集器需要将此解析为 Multi*Reader 的 docID 空间,您必须通过记录最近 setNextReader 调用中的 docBase 来重新设置它。

  3. TopDocsCollector 是 TopFieldCollector(按字段排序)和 TopScoreDocCollector(按分数排序)的基类。如果您正在编写按分数排序的自定义收集器,那么扩展 TopScoreDocCollector 可能更容易。

另外:最简单的收集器示例是 TotalHitCountCollector!