2015-01-09 1 views
0

Я построил запрос в lucene, чтобы заменить SQL-запрос, но пришел к выводу, что запрос lucene является порядком порядка нескольких величин. С медленным я имею в виду, от 250 мс до 5000 мс, поэтому неприемлемо. Настройка немного особенная, и я полагаю, где проблема.Lucene TwoWayFieldBridge медленный запрос

Основное поле, индексирования и поиска по имеет тип Map<String, String> и сопоставляется с:

@ElementCollection(targetClass = String.class) @CollectionTable(name = "data") private Map<String, String> data;

Или, другими словами, этот объект имеет ассоциированную таблицу с ключевыми парами значений. Мы хотим искать эти значения, но только на определенных ключах. Таким образом, моя реализация на полевом мостике сделает запись в документе, если мы столкнемся с ключом, который отвечает нашим потребностям. (Очевидно, что мы не хотим, чтобы хранить каждый ключ в индексе.)

Основной запрос на самом деле ничего особенного:

FullTextSession fullTextSession = Search.getFullTextSession(getCurrentSession()); 
try { 
    fullTextSession.createIndexer(Form.class).startAndWait(); 
} catch (InterruptedException ex) { 
    LOG.error("Exception when indexing: ", ex); 
} 
QueryBuilder builder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Entity.class).get(); 
org.apache.lucene.search.Query query; 
BooleanJunction booleanJunction = builder.bool(); 

booleanJunction.must(builder.keyword().onFields("data") 
.matching(searchString).createQuery()); 

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


Update: Принятый ответ является правильным в том смысле, что это вызвало значительный спад. Я рекомендую либо проиндексировать ваше приложение с самого начала, и если это невозможно, вы можете присоединить своего рода startuplistener (в зависимости от используемой структуры или контекста) и использовать этот код для запуска индексатора. Обратите внимание, что вам нужно открыть достаточно доступных подключений, или это может заблокировать ваше приложение от запуска.

ответ

1

Если код, показывающий ваш «код поиска», то ваша проблема заключается в том, что вы индексируете данные по каждому отдельному поиску. Это индексирует Form класс:

try { 
    fullTextSession.createIndexer(Form.class).startAndWait(); 
} catch (InterruptedException ex) { 
    LOG.error("Exception when indexing: ", ex); 
} 

Вы только хотите сделать это один раз, или при изменении данных. В коде используется API индексатора индексирования для индексации существующих данных (createIndexer(Form.class).startAndWait()). Цель этого метода - создать начальный индекс существующих данных. После индексирования данных вы можете, например, полагаться на автоматическую индексацию Hibernate Search, которая будет регистрировать прослушиватель для изменения данных и только индексировать данные, которые будут добавлены или изменены. В качестве альтернативы вы можете вручную индексировать, если вы хотите/нуждаетесь в этом уровне контроля. Я рекомендую вам обратиться к документации, чтобы узнать больше об этих различных типах индексирования.

+0

Я забыл обновить этот вопрос, но вы действительно правы. Теперь я обрабатываю это при запуске, и это вызвало значительное ускорение; Однако я обнаружил, что реальное замедление произошло от моего ngramfilter на 3 символа, что было довольно медленным, хотя используемые данные были невысокими. Я переключился на «WildCardQuery», который значительно быстрее, если не найдено много хитов. Мне на самом деле не нужен ответ, потому что он достаточно быстрый, но я действительно задаюсь вопросом, почему это замедление. Спасибо за Ваш ответ – froginvasion