2012-05-03 13 views
0

私はLuceneを使用してIListを索引付けするという退屈な問題があります。またHibernate SearchとLucene ILISTの最初の索引付け

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

、インデックス作成のためのフィールド属性使用されるいくつかの他のプロパティ:インデックス作成のためのエンティティをマークした後

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

は、私が持っている

私のエンティティは、私はこのようなIndexedEmbedded属性を適用するIListが含まれています1200万行の初期索引作成を行います(バッチ処理を使用)。 BookAdditionalInfosというIListのインデックスを作成するまでは、すべてが完璧に機能します。このIndexedEmbedded属性がない場合(またはこのIListをインデックス化しない場合)はすべて正常であり、Field属性を持つすべてのプロパティーマークがインデックスされます。

私はFluent NHibernateを使用しています。

何が問題になりますか?また、私はhttp://ayende.com/blog/3992/nhibernate-searchに見えたが、いずれの結果

せずに問題がある:私は、インデックスのIListにしようとすると、インデックスは永遠に取って、何もインデックスされません。

はあなたに

EDITありがとうございましたこのIListを索引付けしないで(またはIListにIndexedEmbeddedを指定しないで)索引付けは正常です。索引付けされた結果が得られます。

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; 
      } 
     } 
+0

問題は何ですか?例外がスローされていますか? –

+0

は例外をスローしません。上記の質問には、私が12百万行の索引付けに使用する初期索引機能が用意されています。私は、IListがIndexedEmbeddedとしてマークしているときに、この関数に何らかの問題があると思います。 – Koste

+1

何か問題があると言うと、何の例外もスローされません。それは永遠にかかりますか?それは間違ってフィールドのインデックスですか? – Prescott

答えて

0

あなたがそこに古典的なN + 1の選択問題を持っているように私には見えます - あなたはあなたの本を選択しているとき、基本的に、あなたがしていますBookAdditionalInfosも選択しないので、NHibernateはインデックス作成中にBookAdditionalInfoを取得するために各書籍ごとに新しいselectを発行する必要があります。 クイックフィックスがにあなたの選択を変更するには、次のようになります。それは同じエンティティのためにあなたに複数の行を与えるBookAdditionalInfoテーブルに参加を行いますので、あなたはおそらく今しかし、あなたのページングと追加の問題に実行されます

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

あなたの結果セットには、次のようなことをしてみることをお勧めします:

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(); 
+0

Martin、あなたの答えに感謝します。私はこのソリューションを試してみましたが、結果はありません。 BookAdditionalInfosも取得しようとしましたが、索引付けされませんでした。ジェネリックリストがIndexedEmbeddedとしてマークされている場合、どちらの書籍もインデックスされません。私は回避策を講じ、BookAdditionalInfoクラスのインデックスを作成し、ブックの参照を保持し、BookエンティティをIndexedEmbeddedとしてマークし、すべてがOKです。あなたの2番目の提案をありがとう。 – Koste

関連する問題