I'm using NHibernate Search for NHibernate 3.0 GA.

I have this code in my product repository:

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

In NH Profiler, I can see that a select statement is issued for every product found. What am I missing?

I found this thread from 2009 but presumably this bug has been fixed.

EDIT [06/06/2011]:

My property mappings as far as associations go are as follows:

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

I don't really want to eager fetch all categories.

有帮助吗?

解决方案 3

I solved this in the end. I realised I had not wrapped the whole thing into a transaction. Once I did, the N+1 issue was gone. Schoolboy error, but hey, you learn by your mistakes.

其他提示

As NHibernate.Search is unstable, I would use (and I did) Lucene.NET directly from my application - just to ask Lucene for objects' Ids and then load it using Session.Load().

Also you could change LazyLoad settings at class mapping level, not at relationship level. Hope it helps.

EDIT: you could specify batch-size for relationships, so they wouldn't cause select N+1 problem

Are you referencing any lazy loaded properties in the product list that is returned by this method? If so, you can change the property mapping to "eager fetch".

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top