2012-08-01 43 views
4

Lucene的默認不允許在搜索方面領先的通配符,but this can be enabled有:瞭解Lucene的領先通配符性能

QueryParser#setAllowLeadingWildcard(true) 

據我所知,使用通配符領先的防止Lucene的使用索引。帶有領先通配符的搜索必須掃描整個索引。

如何演示領先的通配符查詢的性能?什麼時候可以使用setAllowLeadingWildcard(true)

我已經建立了與模板10萬個文檔的測試指標:

{ name: random_3_word_phrase } 

該指數是360M的磁盤上。

我的測試查詢執行得很好,我一直無法真正演示性能問題。例如,查詢name:*ing可在不到1秒的時間內生成超過110萬份文檔。查詢name:*ing*可同時生成超過150萬份文檔。

這是怎麼回事?爲什麼不這麼慢? 10,000,000份文件不夠?文件是否需要包含不止一個字段?

+0

你需要一個更大的索引。嘗試下載維基百科數據集和索引,然後重新測試... – GalacticJello 2012-08-01 20:18:38

+0

@GalacticJello在更多文檔中變得更大?每個文檔有更多字段?更長的領域? – 2012-08-01 20:33:36

+2

你沒有提到lucene的版本。也許你已經知道,但4。0(目前的alpha版本)包含一些改進,使通配符搜索速度更快。 – javanna 2012-08-02 08:18:19

回答

6

取決於您擁有多少內存以及內存中有多少令牌索引。

360MB總索引可以在任何舊電腦上很快搜索到。一個360GB的索引需要更長的時間...;)

作爲一個例子,我激發了一箇舊的2GB索引,並搜索「* e」。

在8GB的盒子上,它在5秒內返回500K點擊。我在只有1GB內存的盒子上嘗試了相同的索引,耗時約20秒。爲了進一步說明,下面是一些通用的C#代碼,它基本上對1000萬個隨機3個單詞短語進行「** E *」類型搜索。

static string substring = "E"; 

private static Random random = new Random((int)DateTime.Now.Ticks);//thanks to McAden 

private static string RandomString(int size) 
{ 
    StringBuilder builder = new StringBuilder(); 
    char ch; 
    for (int i = 0; i < size; i++) 
    { 
     ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))); 
     builder.Append(ch); 
    } 

    return builder.ToString(); 
} 

static void FindSubStringInPhrases() 
{ 
    List<string> index = new List<string>(); 

    for (int i = 0; i < 10000000; i++) 
    { 
     index.Add(RandomString(5) + " " + RandomString(5) + " " + RandomString(5)); 
    } 

    var matches = index.FindAll(SubstringPredicate); 

} 

static bool SubstringPredicate(string item) 
{ 
    if (item.Contains(substring)) 
     return true; 
    else 
     return false; 
} 

畢竟千萬階段已加載到列表中,它仍然只需要大約一秒鐘的「VAR匹配= index.FindAll(SubstringPredicate);」返回超過400萬次點擊。

問題是,內存很快。一旦事情不再適應內存,你必須開始交換磁盤,當你要看到性能命中。

1

如果我理解正確,索引的一部分是術語詞典,它是所有索引術語的排序列表。當沒有通配符或尾隨通配符搜索時,Lucene可以利用許多術語具有通用前綴的事實。另一方面,使用領先的通配符進行搜索會掃描整個術語字典。這並不是最佳的,但詞典這個術語與索引的其他部分(如頻率和位置數據)相比往往很小,因此對詞典這個術語的全面掃描本身通常不是什麼大問題。