Filtering on custom property with .Where(), performance question
Hello,
In our site, we have a doc type of 'Article', which has a property (contentPicker2) for selecting from another doc type, 'Bios' -- this associates an author to an article. Pulling the author name into the articles is pretty straightforward; we get the ID of the node and pull the properties from there, displaying the author's name from the Bio pages on the Article pages:
@{
IPublishedContent typedContentPicker = Model.Content.GetPropertyValue<IPublishedContent>("author");
if (typedContentPicker != null) {
var authorID = Model.Content.GetPropertyValue<string>("author");
<li><a href="@Umbraco.Content(authorID).Url"> @Umbraco.Content(authorID).Name</a></li>
}
}
Now I'm trying to do the opposite -- display articles that have been tagged with the author on their Bio page. I just need to pull from the Article content, and filter on articles that have been tagged with the current page's ID (the author selected in the content picker on the Article page). What I have now works:
-- but it is crazy slow to load. There are around 10k articles, so I can see why this might be the case.
My question to the Umbraco gurus out there -- is there anything obvious that I am doing wrong here to cause the slow load time, or is it just the size of the query? If it is the size of the query, I'm assuming the solution might be to pull the results from an Examine index.
The quick answer is yes, if you've got 10k nodes then doing a linq query over that many children won't be the fastest thing to do.
Examine will be a lot faster, it can be a little fiddly to set up but probably worthwhile in your case.
If you don't want to go into Examine, you could also look at optimising your linq query and see if that helps. You've got 2 separate Where clauses which you could probably combine into one, for example, and there may be a more efficient way to get the list of children by using Umbraco.TypedContentAtXPath() which is usually very fast. Also IPublishedContent objects have a Children property which will be more efficient than the Children() method.
Finally, you could cache the results of the query on each author's page so that after the first load, it can just grab the list of articles from the cache.
Just one point on your first code example, you could optimise this a fair bit too:
As you've already got the node in your first query, you don't need to get it again to show the Url and Name.
Note also that using Umbraco.Content returns a dynamic object, you might be better off using Umbraco.TypedContent to get the strong IPublishedContent object instead.
Filtering on custom property with .Where(), performance question
Hello, In our site, we have a doc type of 'Article', which has a property (contentPicker2) for selecting from another doc type, 'Bios' -- this associates an author to an article. Pulling the author name into the articles is pretty straightforward; we get the ID of the node and pull the properties from there, displaying the author's name from the Bio pages on the Article pages:
Now I'm trying to do the opposite -- display articles that have been tagged with the author on their Bio page. I just need to pull from the Article content, and filter on articles that have been tagged with the current page's ID (the author selected in the content picker on the Article page). What I have now works:
-- but it is crazy slow to load. There are around 10k articles, so I can see why this might be the case. My question to the Umbraco gurus out there -- is there anything obvious that I am doing wrong here to cause the slow load time, or is it just the size of the query? If it is the size of the query, I'm assuming the solution might be to pull the results from an Examine index.
Any tips would be appreciated, thanks
The quick answer is yes, if you've got 10k nodes then doing a linq query over that many children won't be the fastest thing to do.
Examine will be a lot faster, it can be a little fiddly to set up but probably worthwhile in your case.
If you don't want to go into Examine, you could also look at optimising your linq query and see if that helps. You've got 2 separate Where clauses which you could probably combine into one, for example, and there may be a more efficient way to get the list of children by using
Umbraco.TypedContentAtXPath()
which is usually very fast. Also IPublishedContent objects have aChildren
property which will be more efficient than theChildren()
method.Finally, you could cache the results of the query on each author's page so that after the first load, it can just grab the list of articles from the cache.
Just one point on your first code example, you could optimise this a fair bit too:
As you've already got the node in your first query, you don't need to get it again to show the Url and Name.
Note also that using
Umbraco.Content
returns a dynamic object, you might be better off usingUmbraco.TypedContent
to get the strong IPublishedContent object instead.Hopefully some of this is useful!
Chris
Hi Chris
Thanks a lot for taking the time to answer, that is super helpful!
No worries Shawn - good luck!
is working on a reply...