2011-02-07 74 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

相關問題