2011-06-24 59 views
15

在閱讀「Lucene in Action 2nd edition」時,我遇到了可用於Lucene結果過濾的類Filter的描述。 Lucene有很多過濾器重複Query類。例如,NumericRangeQueryNumericRangeFilter{Filter}比{Lucene}中的{Query}更快嗎?

該書說NRFNRQ完全一樣,但沒有文檔評分。這是否意味着如果我不需要得分或排序文檔文檔字段值我應該更喜歡Filter ing從性能的角度來看Query

+0

數據庫位於本地還是位於不同的服務器上? –

+0

數據庫存儲在本地。在幾臺服務器上,我們也有SSD驅動器。 –

回答

12

我收到烏韋·辛德勒一個偉大的答案,讓我在這裏貼一次。

如果你不緩存過濾器,查詢將更快,因爲ConjunctionScorer 在Lucene中有優化,這是目前不用於過濾器。 如果緩存它們(例如,如果您始終對應用於其所有查詢的特定用戶具有相同的訪問限制),則篩選器很好。在 這種情況下,過濾器只執行一次並緩存所有進一步的 請求,然後與查詢結果集相交。

如果你只想要例如隨機「過濾」例如通過可變數字範圍 類似於地理搜索中的邊界框,使用查詢,查詢在大多數情況下爲 (例如,範圍查詢和類似的東西 - 稱爲MultiTermQueries - 在內部也由相同的BitSet算法實現,如 過濾器 - 實際上它們只是由Scorer-impl包裝的過濾器)。但是 Scorer將查詢和您的「過濾器」查詢結合在一起 (ConjunctionScorer)通常比搜索後應用 過濾器的代碼更快。這可能會有所改進,但一般而言, 過濾器在Lucene中是不再需要的,因此 已經是一些使過濾器和查詢相同的方法,而且還可以緩存非計分查詢。這會使代碼的許多 更容易。

過濾器可以帶來巨大的速度提升使用Lucene 4.0,如果他們是 插入ontop的的的IndexReader前得分, 過濾文件的但還沒有實現(見 https://issues.apache.org/jira/browse/LUCENE-3212) - 我的工作就可以了。我們 也可能使過濾器隨機訪問(它很容易,因爲它們是位集),其中 也可以改善查詢後過濾。但是,如果他們可以支持查詢(如 僅基於FieldCache),那麼我也會使查詢部分隨機訪問( )。

烏韋

1

如果過濾器將被重新使用,由於高速緩存的目的,使用它代替查詢是明智的。如果您不打算使用評分或字段值,則使用過濾查詢也很有意義。

希望這會有所幫助。

8

與丹尼斯的回答相反:不,您可能不想使用過濾器,除非您要多次重複使用相同的查詢。

一個NumericRangeFilter只是MultiTermQueryWrapperFilter一個子類,這意味着,基本上它是這樣的:

for each document in index: 
    if document matches query: 
     match[i] = 1 
    else 
     match[i] = 0 

所以它會在你的指標,而不是對數時間像一個正常的查詢以線性時間運行。

此外,過濾器將佔用更多的內存(索引中每個文檔都有一位)。

如果您打算一遍又一遍地使用相同的查詢,那麼它可能值得您支付一次性能/內存命中次數,並且以後使用速度會更快。但是,如果這是一次性查詢,那幾乎肯定不值得。

(另外,如果你要重複使用,使用CachingWrapperFilter使過濾器緩存。)

1

http://wiki.apache.org/lucene-java/ImproveSearchingSpeed這似乎暗示使用過濾器,而不是查詢發現這一點。直觀地說,它對我來說更有意義,因爲它們幾乎都應該做同樣的事情,唯一的區別是過濾器沒有用於分數。

考慮使用過濾器。將 結果限制爲使用緩存位集過濾器而不是使用查詢子句的 的部分索引可能更有效。對於匹配大量索引大量文檔的限制 尤其如此。篩選器通常用於將結果限制爲一個類別,但在許多情況下可能會用 替換任何查詢子句。使用查詢和過濾器的 之間的一個區別是查詢對 得分有影響,而過濾器則沒有。