GetMany() without IDs

Topics: Customizing Orchard
Jan 9, 2014 at 2:29 AM
I'm trying to batch load a set of content items of a specific set of content types; I only need a few properties of each content item (title, publish status, last modified date). I need to return these items via WebAPI.

Here is what I'm doing today (pseudo-code):

var types = new string[] { "Foo", "Bar", "Baz", "Biz", "Buz" }

IContentManager.Query(VersionOptions.Latest, types).Slice(0, 10).ToList().AsQueryable();

What I'm finding is that each content item winds up being loaded individual, meaning a roundtrip for each content item. That really kills my perf. If I had the set of Id's of my content items, I understand that GetMany() would batch the load and reduce the number of round trips; is there any way to perform a GetMany() when all I have is content type name?

Open for any suggestions! TIA!
Jan 9, 2014 at 5:11 AM
Edited Jan 9, 2014 at 5:11 AM
After spending some additional time on this, I was able to significantly reduce the number of round trips by constructing an HqlQuery and eagerly loading the records of the parts I require properties from.
return _contentManager.HqlQuery()
                .ForType(types)
                .ForVersion(VersionOptions.Latest)
                .Include("TitlePartRecord", "AutoRoutePartRecord", "BodyPartRecord", "CommonPartRecord")
                .List()
                .AsQueryable();
The SQL query is still awfully noisy - I'm pulling back lots of data that I'm not going to use - but overall cost relative to lazily loading each property and the cost of the round trip seems to be improved considerably. I'll call it an 8 bannana improvement, since I have no hard and fast metrics. Perhaps a three-squirrel improvement.

Bryan

Developer
Jan 12, 2014 at 12:57 PM
Query() loads all the content items in a single query, not one by one. What I assume you're seeing is that all used parts' record are loaded for each of the content items one by one (e.g. TitlePartRecord for item one once you access it, then for item2...).

With Orchard 1.8 this extra round trip is eliminated. In the mean time you could use WithQueryHints() to eager-load the records of those content parts that you want to access (and the resulting SQL would be something like the one you get with your HQL).