极慢的手动索引?

时间:2011-03-03 22:37:14

标签: nhibernate lucene.net nhibernate.search

我正在尝试将数据库中已有的大约21,000个实体添加到nhibernate-search Lucene索引中。完成后,索引大约为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 个答案:

答案 0 :(得分:1)

通过使用批处理和事务的组合,我已经能够加快相当多的索引。

我的初始代码花了大约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;
        }
    }

答案 1 :(得分:-1)

这取决于您可以设置的lucene选项。请参阅this page并检查nhibernate-search是否包含这些选项的包装器。如果没有,请修改其来源。