2011-02-07 78 views
9

在Lucene中给定查询的所有结果进行计数的最快方法是什么?在Lucene中计算所有结果的最快方法(java)

  1. TopDocs.totalHits
  2. 实施和管理器,使用QueryFilter
  3. 实现自定义的 '计算' 收藏家。这只是在collect(int doc)方法中增加一个计数,并为accepDocOutOfOrder()方法返回true。所有其他方法都是NOOPS。

由于1.将对所有文档进行评分,并且2.由于加载FieldCache可能会有前期打击,因此我认为答案是3. Lucene没有提供这样的收藏家开箱即用?

回答

1

你说得对,#3会更快,但我不认为这是因为得分。有一种更快的方法,如果你不关心背后的推理,可以跳到底部。

#1的性能损失来自于TopDocs收集器会将文档保留在优先级队列中的事实,这意味着您将失去一些按分数排序的时间。 (你也会吃掉一些内存,但是因为你只是存储一堆int + float对,所以它可能非常小。)

至于为什么Lucene不提供这种开箱即用的功能:不想查找所有结果。这就是为什么当你搜索时,你说只能找到顶部n结果。有这strong theoretical reasons。即使谷歌说“显示 n结果”。

所以我给你的建议如下:如果你有一个合理数量的结果,那么使用TopDocs.totalHits不会在性能方面太糟糕。如果totalHits方法给您带来问题,我不认为自定义收集器会好得多。 (TopDocs.totalHits将在n个时间运行,自定义收集器将是线性的。根据您的设置,日志n系数可能是相关的,或者它可能不相关。)

因此,如果您绝对需要此功能和TopDocs.totalHits太慢,我会建议查看搜索项的文档频率。你可以假设频率是独立的(所以p(A和B)= p(A)* p(B))并且从那里做一个相当好的猜测。它会非常快,因为它只是每个术语的恒定时间查找。

+0

感谢您的回答。在这个阶段,我们将使用TotalHitCountCollector。我们的数据集仍然很小,可以准确计数。我会保留你所描述的术语频率方法 - 这确实听起来是最快的方法。 – npellow 2011-02-07 21:48:31

+0

我想知道Google如何做到这一点。很明显,它并没有真正回归“前25名”的结果。如果是,那么它应该知道结果的总数是检查所有其他结果的副作用,以发现它们不在前25位。我的理论是它将返回25个基本上任意“值得存在最高“的结果。 – Trejkaz 2011-03-15 01:21:54

相关问题