1

我正在尝试将数据库中已有的大约 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 的选项。

会议清除和驱逐只是我绝望的举动-我还没有看到它们以某种方式产生影响。

有没有人成功地快速索引大量现有数据?

4

2 回答 2

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;
        }
    }
于 2012-01-27T16:48:17.403 回答
-1

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

于 2011-03-03T22:45:36.543 回答