2010-07-22 125 views
14

通配符*只能用於單詞的末尾,如user*如何用「like」運算符查詢lucene?

我想查詢一個像%user%,該怎麼做?

+0

有點類似的問題:[http://stackoverflow.com/questions/468279/lucene-net-leading-wildcard-character-throws-an-error](http:// stackoverflow.com/questions/468279/lucene-net-leading-wildcard-character-throws-an-error) – devson 2010-07-22 10:43:14

回答

9

Lucene提供了ReverseStringFilter,允許像*用戶那樣進行通配符搜索。它通過以相反順序索引所有術語來工作。

但我認爲沒有辦法做類似'LIKE%user%'的事情。

+2

有趣。實際上,這意味着您需要提前設置您的索引以允許引用通配符。從查看bug(https://issues.apache.org/jira/browse/LUCENE-1398),似乎只能指定一個通配符,但不能在同一個術語中使用尾隨符號(因爲那樣你重新回到同樣的問題)。 – Jon 2010-07-22 12:00:16

6

由於Lucene的2.1,你可以使用

QueryParser.setAllowLeadingWildcard(true); 

但這可以殺死性能。 LuceneFAQ有一些這方面的更多信息。

3

當你考慮這個問題時,lucene對通配符的支持通常被限制在一個單詞模式結尾的通配符並不令人驚訝。

關鍵字搜索引擎通過創建語料庫中所有單詞的反向索引來工作,該單詞按語序排序。當您執行正常的非通配符搜索時,引擎會利用這樣的事實,即索引條目經過排序以在O(logN)步驟中找到您的單詞的條目或條目,其中N是單詞或條目的數目。對於帶有後綴通配符的單詞模式,發現第一個匹配單詞時會發生同樣的情況,通過掃描條目直到模式的固定部分不再匹配,可以找到其他匹配。

然而,對於一個通配符前綴通配符後綴的單詞模式,發動機要看看索引中的所有條目。這將是O(N) ...除非引擎構建了一堆用於匹配單詞的文字子串的二級索引。 (這樣會使索引變得更加昂貴)。而對於更復雜的模式(例如正則表達式),這個問題對於搜索引擎會更糟糕。

14

LIKE查詢的麻煩在於它們在執行時間方面是expensive。您可以設置的QueryParser,讓領先的通配符如下:

QueryParser.setAllowLeadingWildcard(true)

,這將允許你這樣做的搜索,如:

*user*

但是,這將需要很長的時間來執行。有時當人們說他們想要LIKE查詢時,他們實際需要的是fuzzyquery。這將允許你做以下搜索:

user~

這將符合條件usersfuser。您可以使用介於0和1之間的浮點值指定查詢中術語與要匹配的術語之間的編輯距離。例如user~0.8可能會匹配比user~0.5更多的術語。

我建議你也看看regex query,它支持Lucene搜索的正則表達式語法。它可能更接近你真正需要的東西。也許是這樣的:

.*user.*