Чрезвычайно медленная ручная индексация? - PullRequest
1 голос
/ 04 марта 2011

Я пытаюсь добавить около 21 000 объектов уже в базе данных в индекс Lucene nhibernate-search. Когда закончите, индексы около 12 мегабайт. Я думаю, что время может немного отличаться, но оно всегда очень медленное. В моем последнем запуске (работающем с отладчиком) индексация данных заняла более 12 минут.

private void IndexProducts(ISessionFactory sessionFactory)
{
  using (var hibernateSession = sessionFactory.GetCurrentSession())
  using (var luceneSession = Search.CreateFullTextSession(hibernateSession))
  {
    var tx = luceneSession.BeginTransaction();
    foreach (var prod in hibernateSession.Query<Product>())
    {
      luceneSession.Index(prod);
      hibernateSession.Evict(prod);
    }
    hibernateSession.Clear();
    tx.Commit();
  }
}

Подавляющее большинство времени проводится в tx.Commit (). Из того, что я читал о поиске в Hibernate, этого следовало ожидать. Я встречал немало способов помочь, таких как MassIndexer, flushToIndexes, пакетные режимы и т. Д. Но, насколько я могу судить, это только опции Java.

Ясное и чистое занятие - это просто отчаянные шаги со стороны меня - я не видел, чтобы они так или иначе имели значение.

Успешно ли кто-нибудь быстро проиндексировал большое количество существующих данных?

Ответы [ 2 ]

1 голос
/ 27 января 2012

Мне удалось значительно ускорить индексацию, используя комбинацию пакетирования и транзакций.

Мой первоначальный код занял ~ 30 минут для индексации ~ 20 000 объектов.Используя приведенный ниже код, я сократил его до ~ 4 минут.

    private void IndexEntities<TEntity>(IFullTextSession session) where TEntity : class
    {
        var currentIndex = 0;
        const int batchSize = 500;

        while (true)
        {
            var entities = session
                .CreateCriteria<TEntity>()
                .SetFirstResult(currentIndex)
                .SetMaxResults(batchSize)
                .List();

            using (var tx = session.BeginTransaction())
            {
                foreach (var entity in entities)
                {
                    session.Index(entity);
                }
                currentIndex += batchSize;

                session.Flush();
                tx.Commit();
                session.Clear();
            }

            if (entities.Count < batchSize)
                break;
        }
    }
0 голосов
/ 04 марта 2011

Это зависит от настроек люцена, которые вы можете установить. См. эту страницу и проверьте, есть ли в nhibernate-search обертки для этих параметров. Если это не так, измените его источник.

...