Старый сайт, который я поддерживаю, использует Zend Lucene (ZF 1.7.2) в качестве поисковой системы. Недавно я добавил две новые таблицы для индексации, которые содержат около 2000 строк текстовых данных размером от 31 байта до 63 КБ.
Индексация работала нормально несколько раз, но после третьего запуска или около того она начала заканчиваться фатальной ошибкой из-за исчерпания выделенной памяти. Ограничение памяти PHP изначально было установлено в 16M, что было достаточно для индексации всего другого контента, 200 строк текста по несколько килобайт каждый. Я постепенно увеличил лимит памяти до 160 МБ, но его все равно недостаточно, и я не могу увеличить его еще больше.
При индексировании мне сначала нужно очистить ранее проиндексированные результаты, потому что схема пути содержит числа, которые Lucene, похоже, воспринимает как стоп-слова, возвращая каждую запись, когда я запускаю этот поиск:
$this->index->find('url:/tablename/12345');
После очистки всех результатов я вставляю их один за другим:
foreach($urls as $v) {
$doc = new Zend_Search_Lucene_Document();
$doc->addField(Zend_Search_Lucene_Field::UnStored('content', $v['data']);
$doc->addField(Zend_Search_Lucene_Field::Text('title', $v['title']);
$doc->addField(Zend_Search_Lucene_Field::Text('description', $v['description']);
$doc->addField(Zend_Search_Lucene_Field::Text('url', $v['path']);
$this->index->addDocument($doc);
}
После примерно тысячи итераций индексатору не хватает памяти и происходит сбой. Странно, удвоение лимита памяти помогает только нескольким десяткам строк.
Я уже пытался настроить параметры MergeFactor и MaxMergeDocs (до значений 5 и 100 соответственно) и вызывать $this->index->optimize()
каждые 100 строк, но ни одна из них не обеспечивает последовательной помощи.
Очистка всего поискового индекса и его перестройка в большинстве случаев приводит к успешной индексации, но я бы предпочел более элегантное и менее ресурсоемкое решение. Я что-то не так делаю? Это нормально, если индексирование занимает так много памяти?