我有一些使用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)]
在标记实体以进行索引之后,我必须对12百万行进行初始索引(使用批处理)。一切都很完美,直到我开始索引名为BookAdditionalInfos的IList。如果没有这个IndexedEmbedded属性(或者没有索引此IList),一切都会正常,并且每个带有Field属性的属性标记都将被编入索引。
我正在使用Fluent NHibernate。
可能有什么问题?
谢谢
编辑:我也看了http://ayende.com/blog/3992/nhibernate-search,但没有任何结果
问题是:当我尝试索引IList时,索引会永远消失,并且不会将任何内容编入索引。如果没有索引这个IList(或没有指定IndexedEmbedded to IList)索引就可以了,我得到了索引结果。
编辑(初始索引功能):
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;
}
}
答案 0 :(得分:0)
在我看来,你有一个经典的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();