2012-02-24 5 views
0

Apache Lucene Java로 색인을 생성 한 매우 큰 데이터베이스 (각각 최대 26 개의 필드가있는 약 3 천만 개의 레코드)가 있습니다.Lucene : IndexSearcher.search()가 매우 큰 데이터베이스에서 Java 힙 공간 오류를 발생시킵니다.

두 필드에서 쿼리를 생성 중입니다. 각 검색어는 9 개의 필드 중 하나에 표시 될 수 있으며 두 검색어가 모두 문서의 관련 필드에 나타나는 경우 내 검색어에서 문서를 반환해야합니다. 쿼리과 같이 구성되어있다 :

Private Query CreateQuery(String theSearchTerm, String theField) throws ParseException 
{ 
    StandardAnalyzer theAnalyzer = new StandardAnalyzer(Version.LUCENE_35); 
    Query q; 
    QueryParser qp = new QueryParser(Version.LUCENE_35, theField, theAnalyzer); 
    qp.setDefaultOperator(QueryParser.Operator.AND); 
    qp.setAllowLeadingWildcard = true; 
    q = qp.parse(theSearchTerm); 
    return q; 
} 

Public ScoreDoc[] RunTheQuery(String searchTerm1, String searchTerm2) 
{ 
    Directory theIndex = new SimpleFSDirectory(new File("C:\\MyDirectory"); 
    IndexSearcher theSearcher = new IndexSearcher(InderReader.open(theIndex)); 

    BooleanQuery theTopLevelBooleanQuery = new BooleanQuery(); 

    BooleanQuery fields1 = new BooleanQuery(); 
    BooleanQuery fields2 = new BooleanQuery(); 
    BooleanQuery fields3 = new BooleanQuery(); 
    BooleanQuery fields4 = new BooleanQuery(); 
    BooleanQuery fields5 = new BooleanQuery(); 
    BooleanQuery fields6 = new BooleanQuery(); 
    BooleanQuery fields7 = new BooleanQuery(); 
    BooleanQuery fields8 = new BooleanQuery(); 
    BooleanQuery fields9 = new BooleanQuery(); 

    BooleanQuery innerQuery = new BooleanQuery(); 

    fields1.add(CreateQuery(searchTerm1, param1), BooleanClause.Occur.MUST); 
    fields1.add(CreateQuery(searchTerm2, param2), BooleanClause.Occur.MUST); 
    fields2.add(CreateQuery(searchTerm1, param3), BooleanClause.Occur.MUST); 
    fields2.add(CreateQuery(searchTerm2, param4), BooleanClause.Occur.MUST); 
    fields3.add(CreateQuery(searchTerm1, param5), BooleanClause.Occur.MUST); 
    fields3.add(CreateQuery(searchTerm2, param6), BooleanClause.Occur.MUST); 
    fields4.add(CreateQuery(searchTerm1, param7), BooleanClause.Occur.MUST); 
    fields4.add(CreateQuery(searchTerm2, param8), BooleanClause.Occur.MUST); 
    fields5.add(CreateQuery(searchTerm1, param9), BooleanClause.Occur.MUST); 
    fields5.add(CreateQuery(searchTerm2, param10), BooleanClause.Occur.MUST); 
    fields6.add(CreateQuery(searchTerm1, param11), BooleanClause.Occur.MUST); 
    fields6.add(CreateQuery(searchTerm2, param12), BooleanClause.Occur.MUST); 
    fields7.add(CreateQuery(searchTerm1, param13), BooleanClause.Occur.MUST); 
    fields7.add(CreateQuery(searchTerm2, param14), BooleanClause.Occur.MUST); 
    fields8.add(CreateQuery(searchTerm1, param15), BooleanClause.Occur.MUST); 
    fields8.add(CreateQuery(searchTerm2, param16), BooleanClause.Occur.MUST); 
    fields9.add(CreateQuery(searchTerm1, param17), BooleanClause.Occur.MUST); 
    fields9.add(CreateQuery(searchTerm2, param18), BooleanClause.Occur.MUST); 

    innerQuery.add(fields1, BooleanClause.Occur.SHOULD); 
    innerQuery.add(fields2, BooleanClause.Occur.SHOULD); 
    innerQuery.add(fields3, BooleanClause.Occur.SHOULD); 
    innerQuery.add(fields4, BooleanClause.Occur.SHOULD); 
    innerQuery.add(fields5, BooleanClause.Occur.SHOULD); 
    innerQuery.add(fields6, BooleanClause.Occur.SHOULD); 
    innerQuery.add(fields7, BooleanClause.Occur.SHOULD); 
    innerQuery.add(fields8, BooleanClause.Occur.SHOULD); 
    innerQuery.add(fields9, BooleanClause.Occur.SHOULD); 

    theTopLevelBooleanQuery.add(innerQuery, BooleanClause.Occur.MUST); 

    TopDocScoreCollector collector = TopDocScoreCollector.create(200, true); 

    //Heap space error occurs here 
    theSearcher.search(theTopLevelBooleanQuery, collector); 

    ScoreDoc[] hits = collector.topDocs().scoreDocs; 
    return hits; 
} 

내 문제는 내가 서버 (윈도우 서버 2003 R2)에서의 java.exe의 프로세스 IndexSearcher.search() 메서드를 호출 할 때 이상 5백40메가바이트을 소비하는 인 Java 힙 공간 오류가 발생합니다. 완벽을 기하기 위해 자바 애플리케이션은 웹 서버 (현재 Oracle Glassfish, Apache Tomcat으로 이동하려하고 있지만)에서 실행 중입니다.

아무도이 힙 공간 오류를 중지하는 방법에 대한 아이디어가 있습니까? StackOverflow 게시물 (http://stackoverflow.com/questions/7259736/cant-open-lucene-index-java-heapspace) 비슷한 문제를 해결하는 것 같다지만, 정말 자세한 답변을 제공하지 않습니다.

Java 프로세스에서 사용할 수있는 메모리 양을 늘릴 수있는 유일한 방법은 무엇입니까? 새로운 검색자를 쓰는 유일한 답은 누구나 경량 검색 자에 관한 좋은 기사를 추천 할 수 있습니까?

위의 코드를 수정하여이 문제를 해결할 수있는 방법이 있습니까?

어떤 도움을 감사, 감사를받은 것, 릭

+0

우리가 어떤 할당으로 인해 OutOfMemoryError가 발생했는지 알 수 있도록 스택 추적? – jpountz

답변

관련 문제