2011-06-03 118 views
0

我正在使用NHibernate搜索NHibernate 3.0 GA。NHibernate搜索N + 1問題

我有這樣的代碼在我的產品資源庫:

public IList<Product> Find(string term) 
     { 
      var productFields = new[] { "Name", "Description" }; 
      var importance = new Dictionary<String, float>(2) { { "Name", 4 }, { "Description", 1 } }; 
      var analyzer = new StandardAnalyzer(); 
      var parser = new MultiFieldQueryParser(
       productFields, 
       analyzer, 
       importance); 

      var query = parser.Parse(term); 

      var session = Search.CreateFullTextSession(NHibernateSession.Current); 
      var tx = session.BeginTransaction(); 
      var fullTextQuery = session.CreateFullTextQuery(query); 
      fullTextQuery.SetFirstResult(0).SetMaxResults(20); 
      var results = fullTextQuery.List<Product>(); 
      tx.Commit(); 

      return results; 
     } 

在NH探查,我可以看到一個select語句是爲找到的每個產品發行。我錯過了什麼?

我從2009年發現this thread,但大概這個bug已經修復。

EDIT [06/06/2011]:

我的屬性映射就如下的協會去:

mapping.HasManyToMany(c => c.Categories) 
       .Table("CatalogHierarchy") 
       .ParentKeyColumn("child_oid") 
       .ChildKeyColumn("oid") 
       .Cascade.None() 
       .Inverse() 
       .LazyLoad() 
       .AsSet(); 

      mapping.HasMany(c => c.Variants) 
       .Table("CatalogProducts") 
       .Where("i_ClassType=2") 
       .KeyColumn("ParentOID") 
       .Cascade.SaveUpdate() 
       .AsSet(); 

我真的不希望急於取回所有類別。

回答

0

我最終解決了這個。我意識到我沒有把整件事情都包裝進交易中。一旦我做到了,N + 1問題就消失了。 小學生錯誤,但嘿,你從錯誤中學習。

0

您是否引用此方法返回的產品列表中的任何延遲加載的屬性?如果是這樣,您可以將屬性映射更改爲「渴望獲取」。

+0

我已將我的映射添加爲編輯。你是說我應該急於加載我的產品。 ... 我怎麼做?用FetchType.Join替換.LazyLoad()? – autonomatt 2011-06-06 12:17:58

+0

是的,應該這樣做。 – 2011-06-06 14:14:24

1

由於NHibernate.Search不穩定,我會直接從我的應用程序中使用Lucene.NET - 只需要向Lucene請求對象的Id,然後使用Session.Load()加載它。

您也可以在類映射級別更改LazyLoad設置,而不是在關係級別。 希望它有幫助。

編輯:您可以指定批量大小的關係,所以他們不會導致選擇N + 1問題

+0

認爲這是一個相當成熟的代碼庫:( – autonomatt 2011-06-06 14:30:27

+0

你是什麼意思的不穩定? – mathieu 2011-08-31 06:44:58

+0

只是通過獲取相關字段和聚合結果,我將我們的應用程序的索引時間從大約20分鐘縮短到小於20秒, NHibernate.Search已經成爲可能。 – jishi 2012-01-31 11:35:46