Lucene: IndexSearcher.search () вызывает ошибку пространства кучи Java в очень большой базе данных - PullRequest
0 голосов
/ 24 февраля 2012

У меня очень большая база данных (около 30 миллионов записей, каждая из которых содержит не менее 26 полей), которую я проиндексировал с помощью Apache Lucene Java.

Я строю запрос из двух полей. Каждый поисковый термин может отображаться в любом из девяти полей, и я хочу, чтобы мой запрос возвратил документ, если оба поисковых термина появляются в любом из соответствующих полей в документе. Запрос структурирован так:

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;
}

Моя проблема заключается в том, что при вызове метода IndexSearcher.search () процесс java.exe на сервере (Windows Server 2003 R2) потребляет более 540 МБ, что приводит к ошибке пространства кучи Java. Для полноты java-приложение работает на веб-сервере (в настоящее время Oracle Glassfish, хотя я планирую перейти на Apache Tomcat).

У кого-нибудь есть идеи, как остановить эту ошибку пространства кучи? Пост StackOverflow (http://stackoverflow.com/questions/7259736/cant-open-lucene-index-java-heap-space), кажется, решает аналогичную проблему, но не дает подробного ответа.

Является ли единственным ответом на увеличение объема памяти, который может использовать процесс Java? Является ли единственным ответом написать новый поисковик, и в этом случае кто-нибудь может порекомендовать хорошую статью об облегченных поисковиках?

Есть ли способ решить эту проблему путем изменения приведенного выше кода?

Любая помощь будет принята с благодарностью, Спасибо, Rik

1 Ответ

2 голосов
/ 24 февраля 2012

Вы можете увеличить пространство кучи Java следующим образом:

java -Xmx6g myprogram

или посмотреть это сообщение: увеличить размер кучи в Java

или: IBMSDK для Java

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...