2017-10-11 76 views
1

A Document是一個公司的僱員數據,其名稱如下:empName, empId, departmentId etc具有多個FuzzyQuery的Lucene BooleanQuery速度太慢

使用自定義分析器已經索引了大約400萬個數據。

搜索查詢有一個listofemployees'name,並且知道列表中的所有員工屬於同一個部門。公司有多個部門。

所以我想要fuzzy search所有員工的名字在給定的department id下。

對於這個我使用布爾查詢,看起來像:

Query termQuery = new TermQuery(new Term("departmentId","1234")); 
BooleanQuery.Builder bld = new BooleanQuery.Builder(); 
for(String str:employeeNameList) { 
    bld.add(new FuzzyQuery(new Term("name",str)), BooleanClause.Occur.SHOULD); 
}  
BooleanQuery bq = bld.build(); 
BooleanQuery finalBooleanQeury = new BooleanQuery.Builder() 
       .add(termQuery, BooleanClause.Occur.MUST) 
       .add(bq, BooleanClause.Occur.MUST).build(); 

現在通過finalBooleanQeurysearch方法IndexSearcher並得到結果。

問題在於其採取太多時間,當employeeNameList more than 50的大小需要大約500 ms進行搜索。

如何將時間從500 ms減少到50 ms

這個問題還有其他解決方案嗎?

+0

爲什麼你要爲每個員工添加布爾子句? – Mysterion

+0

@Mysterion有沒有其他方法可以做到這一點? –

回答

1

如果你看看FuzzyQuery的其他構造函數,你會看到一些簡單的方法來提高性能。每個額外的參數都有助於您減少FuzzyQuery將要執行的工作量,從而提高性能。

首先,也是最重要的:

  • 前綴長度:我強烈建議將其設置爲非零值。這是多少個字符在開始的時候不會被模糊匹配。因此,如果搜索前綴爲1的「abc」,則「abb」和「acc」會匹配,但不匹配「bbc」。這允許lucene在嘗試查找匹配項時使用索引,而不必掃描整個詞典。很可能你會在這裏看到最大的性能提升。許多人似乎發現,在性能和滿足搜索需求之間是一個很好的平衡點。

的可用剩餘參數還可以幫助:

  • maxEdits - 2是默認的,最大。將它設置爲1將會減少,因此工作得更快。

  • maxExpansions - 在引擎蓋下,該查詢找到與模糊參數相匹配的術語,然後執行這些術語的搜索。如果您正在尋找短期條款,特別是匹配條款列表可能會很長。設置maxExpansions將防止發生這些非常長的匹配列表。默認值爲50.

  • 換位 - 是否允許交換兩個字符是允許的編輯。默認值是true。基本上,Levenshtein和Damerau-Levenshtein之間的區別。假工作少,匹配少,所以表現會更好。不知道這個差別是否會很大。

+0

感謝您的回答,我已經通過其他構造函數與其他參數。但是在設置參數方面有一些限制。 **前綴長度**:在索引過程中,我使用** DoubleMetaphoneFilter **,所以修復前綴長度可以改變結果。 ** maxEdits **:員工姓名可能有超過1的拼寫錯誤,無法將maxEdits更改爲1. ** maxExpansions **:只有少數情況可以提供幫助。 **換位**:這也可以幫助,但不會交換字符時得到預期的模糊結果。 –