2008-10-12 84 views

回答

5

理想情況下,應該有一個實用工具來做到這一點,但我不知道。但是,以合理高效的方式「手動」操作並不難。我假設您已經有一個Query和/或Filter對象,您可以使用它來定義感興趣的子集。

首先,在您的索引子集中的內存中建立所有文檔ID。您可以使用IndexSearcher.search(Query, Filter, HitCollector)快速完成此操作; HitCollectordocumentation包括一個看起來應該起作用的示例,或者您可以使用其他容器來存儲您的文檔ID。

接下來,初始化一個空的HashMap(或其他)以將術語映射到總頻率,並通過爲每個感興趣的文檔和字段調用IndexReader.getTermFreqVector方法之一來填充映射。三個參數的形式似乎更簡單,但要麼應該沒問題。對於三參數表單,您可以製作一個TermVectorMapper,其map方法檢查term是否在地圖中,如果不是,則將其與frequency關聯,或者如果是,則將frequency添加到現有值。請確保在此過程中跨getTermFreqVector的所有調用使用相同的TermVectorMapper對象,而不是爲循環中的每個文檔實例化一個新對象。你也可以通過重寫isIgnoringPositions()isIgnoringOffsets()來加快速度;你的對象應該返回true這兩個。它看起來像你的TermVectorMapper也可能被迫定義一個setExpectations方法,但那個不需要做任何事情。

一旦你建立了你的地圖,只需按降序對地圖項進行排序,然後讀出你喜歡的許多頂級字詞。如果您事先知道您需要多少條款,您可能更喜歡使用某種基於堆的算法,以線性時間的形式查找頂級項目,而不是使用O(n n n)sort 。我想在實踐中這種普通的舊類型會很快。但這取決於你。

如果您願意,可以通過讓您的HitCollector直接調用getTermFreqVector來結合前兩個階段。這當然應該產生同樣正確的結果,並且直觀地看起來會更簡單和更好,但是文檔似乎警告說這樣做可能比兩遍方法慢很多(與HitCollector示例相同的頁面上以上)。否則我可能會誤解他們的警告。如果你覺得雄心勃勃,你可以嘗試兩種方式,比較,並讓我們知道。

+1

不會這真的很慢,尤其是如果有很多命中? – jjxtra 2011-05-28 17:15:36

0

計算TermVectors將會起作用,但如果有大量文檔需要迭代,將會變慢。另外請注意,如果您是通過排名靠前的術語來表示docFreq,那麼請不要使用TermFreqVector中的計數將這些術語計爲二進制。

或者,您可以迭代像facet counts這樣的術語。每學期使用cached filter;他們的BitSets可用於快速交點計數。

相關問題