2009-12-10 62 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:*”这样的搜索会将正文字段中的每一个字段加载到内存中。

我的建议是在运行通配符查询时运行内存分析器并查看获得的结果。如果通配符查询是罪魁祸首,那么至少应禁用前导通配符,或者降低查询子句的限制。