2009-12-10 63 views
3

我的Lucene索引中的每個文檔都與stackoverflow中的文章類似,我試圖通過索引(其中包含數百萬個文檔)進行搜索。每個用戶只能搜索用戶的公司帖子。我無法控制數據是如何編制索引的,我只需要在它上面實現一個簡單的搜索(可以工作)。在Java中實現Lucene搜索的最佳實踐

這是我的第一稿:

String q = "mysql" 
String companyId = "1001" 

String[] fields = { "body", "subject", "number", "category", "tags"}; 

Float float10 = new Float(10); 
Float float5 = new Float(5); 

Map<String, Float> boost = new HashMap<String, Float>(); 
boost.put("body", float10); 
boost.put("subject", float10); 
boost.put("number", float5); 
boost.put("category", float5); 
boost.put("tags", float5);; 

MultiFieldQueryParser mfqp = new MultiFieldQueryParser(fields, new StandardAnalyzer(), boost); 
mfqp.setAllowLeadingWildcard(true); 
Query userQuery = mfqp.parse(q); 

TermQuery companyQuery = new TermQuery(new Term("company_id", companyId)); 

BooleanQuery booleanQuery = new BooleanQuery(); 
BooleanQuery.setMaxClauseCount(50000) 
booleanQuery.add(userQuery, BooleanClause.Occur.MUST); 
booleanQuery.add(companyQuery, BooleanClause.Occur.MUST); 

FSDirectory directory = FSDirectory.getDirectory(new File("/tmp/index")); 
IndexSearcher searcher = SearcherManager.getIndexSearcherInstance(directory); 
Hits hits = searcher.search(booleanQuery); 

其主要工作功能,但我看到了一些內存問題。每4,5天我會發生Out of Memory錯誤,並且我使用堆轉儲,並看到Lucene Term和TermInfo對象位於列表的首位。我正在使用IndexSearcher的單例實例,我只能在堆中看到它的一個實例。

任何評論我在做的方式?我做錯了什麼,我能做得更好嗎?

+0

設置沒問題,但問題無可救藥。你的意思是說有內存泄漏?你怎麼知道的?你有什麼證據? – 2009-12-10 20:48:00

+0

已編輯。希望它現在更清楚。 – Langali 2009-12-10 20:56:41

+0

您是否使用http://www.eclipse.org/mat/進行分析? – akuhn 2009-12-11 00:59:56

回答

1

你的代碼中沒有明顯的錯誤(至少不是我所知道的)。最好用比visualvm更強大的工具來分析你的heapdump。我建議使用eclipse的Memory Analyzer (MAT)(默認情況下不安裝,但可從默認更新站點獲得)。這很棒。

如果您需要使用MAT的幫助,請參閱Markus Kohler的博客文章"Eclipse Memory Analyzer, 10 useful tips/articles"。他是該工具的作者。

0

你通常在哪裏遇到內存不足的問題?它圍繞着這個街區嗎?

MultiFieldQueryParser mfqp = new MultiFieldQueryParser(fields, new StandardAnalyzer(), boost); 
mfqp.setAllowLeadingWildcard(true); 
Query userQuery = mfqp.parse(q); 

另外,你是否運行與索引過程一起查詢的代碼?

+0

索引器和搜索器在兩個不同的系統上運行。 我認爲它與我在索引中的列號以及文檔數量沒有關係,這導致它爲每個多字段搜索創建了大量的術語。 – Langali 2009-12-14 19:18:56

1

你的堆大小是多少?是否有某些搜索導致您的內存使用率變高?

我的猜測是,當您執行通配符查詢時,您正在打OOME。在內部,Lucene將通配符查詢展開爲與所有匹配通配符的術語的OR查詢。這個問題由於你允許領先的通配符而加劇了。運行像「body:*」這樣的搜索會將正文字段中的每一個字段加載到內存中。

我的建議是在運行通配符查詢時運行內存分析器並查看獲得的結果。如果通配符查詢是罪魁禍首,那麼至少應禁用前導通配符,或者降低查詢子句的限制。