【问题标题】:NHibernate Search and Lucene initial indexing of IListIList 的 NHibernate Search 和 Lucene 初始索引
【发布时间】:2012-05-03 16:00:06
【问题描述】:

我在使用 Lucene 索引 IList 时遇到了一些无聊的问题,我无法解决。

我的实体包含 IList,我像这样应用 IndexedEmbedded 属性:

[ScriptIgnore] //will not serialize
[IndexedEmbedded(Depth = 1, Prefix = "BookAdditionalInfos_"]
public virtual IList<BookAdditionalInfo> BookAdditionalInfos { get; set; }

另外,一些其他属性使用 Field 属性进行索引:

[Field(Index.Tokenized, Store = Store.Yes)]

在为索引标记实体后,我必须对 1200 万行进行初始索引(使用批处理)。在我开始索引名为 BookAdditionalInfos 的 IList 之前,一切都很完美。没有这个 IndexedEmbedded 属性(或没有索引这个 IList)一切正常,每个带有 Field 属性的属性标记都将被索引。

我正在使用 Fluent NHibernate。

可能是什么问题?

谢谢

编辑:我也查看了http://ayende.com/blog/3992/nhibernate-search,但没有任何结果

问题是:当我尝试为 IList 编制索引时,索引会永远占用并且不会编制任何索引。没有索引这个 IList(或没有指定 IndexedEmbedded 到 IList)索引是可以的,我得到了索引结果。

EDIT(初始索引功能):

public void BuildInitialBookSearchIndex()
        {
            FSDirectory directory = null;
            IndexWriter writer = null;

            var type = typeof(Book);

            var info = new DirectoryInfo(GetIndexDirectory());

            //if (info.Exists)
            //{
            //    info.Delete(true);
            //}

            try
            {
                directory = FSDirectory.GetDirectory(Path.Combine(info.FullName, type.Name), true);
                writer = new IndexWriter(directory, new StandardAnalyzer(), true);
            }
            finally
            {
                if (directory != null)
                {
                    directory.Close();
                }

                if (writer != null)
                {
                    writer.Close();
                }
            }

            var fullTextSession = Search.CreateFullTextSession(Session);

            var currentIndex = 0;
            const int batchSize = 5000;

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

                using (var tx = Session.BeginTransaction())
                {
                    foreach (var entity in entities)
                    {
                        fullTextSession.Index(entity);
                    }

                    currentIndex += batchSize;

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

                if (entities.Count < batchSize)
                    break;
            }
        }

【问题讨论】:

  • 有什么问题?是否抛出异常?
  • 不抛出异常。上面的问题提供了我用于索引 1200 万行的初始索引函数。我猜这个函数有问题,当 IList 被标记为 IndexedEmbedded
  • 我很困惑,当您说问题时,您是什么意思,没有抛出异常,OK。它需要永远吗?它是否错误地索引了该字段?
  • 普雷斯科特,谢谢您的回复。问题是:当我尝试索引 IList 时,索引会永远占用并且不会索引任何内容。没有索引这个 IList(或没有指定 IndexedEmbedded 到 IList)索引是可以的,我得到了索引结果。

标签: nhibernate search lucene.net


【解决方案1】:

在我看来,您在那里遇到了一个经典的 N+1 选择问题 - 基本上,当您选择书籍时,您并没有同时选择 BookAdditionalInfos,因此 NHibernate 必须为每个选择发出新的选择以及在索引时检索该书的 BookAdditionalInfo 的每本书。 一个快速的解决方法是将您的选择更改为:

   var entities = Session
                .CreateCriteria<Book>()
                .SetFetchMode("BookAdditionalInfos", FetchMode.Eager)
                .SetResultTransformer(Transformers.DistinctRootEntity)
                .SetFirstResult(currentIndex)
                .SetMaxResults(batchSize)
                .List();

您现在可能会遇到与分页有关的其他问题,因为它会连接 BookAdditionalInfo 表,从而为您的结果集中的同一实体提供多行,因此您可能希望考虑执行以下操作:

   var pagedEntities = DetachedCriteria.For<Book>()
                .SetFirstResult(currentIndex)
                .SetMaxResults(batchSize)
                .SetProjection(Projections.Id());

   var entities = Session
                .CreateCriteria<Book>()
                .Add(Property.ForName("id").In(pagedEntities))
                .SetFetchMode("BookAdditionalInfos", FetchMode.Eager)
                .SetResultTransformer(Transformers.DistinctRootEntity)
                .List();

【讨论】:

  • 马丁,谢谢你的回答。我尝试了这个解决方案,但没有任何结果。我也尝试获取 BookAdditionalInfos,但它没有索引。当通用列表被标记为 IndexedEmbedded 时,这两本书都不会被索引。我做了解决方法,我索引了 BookAdditionalInfo 类,在其中我保持对 Book 的引用并将 Book 实体标记为 IndexedEmbedded,一切都很好。感谢您的第二个建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-11
  • 2015-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-16
相关资源
最近更新 更多