EPiServer Find, GetResult & GetContentResult
By now most of us have probably gotten an EPiServer Find solution up and running. And, if you’re like me, you think it’s absolutely fantastic.
A while I ago I had the idea of implementing EPiServer Find as a cache layer when a website with a high-volume of visitors had been recycled and the in-memory cache cleared. If you’ve worked with one of these sites you’ll know that the database can take quite a hit when the website is warming up. The idea was quite simple: if the page data wasn’t in memory, go fetch it using Find instead until it was available from the in-memory cache. Because when you think about it an index can act as a really kick-ass denormalized view of your data. No real logic, just query the content by ID and serve it back.
But… it didn’t really work out. Partially because things went bump in the code, partially because it’s really not a clever solution to send all that data over the wire. Also, in the unlikely intance that somewhere in your code you should use the content data retrieved from EPiServer Find and save it back to the database, things could get messy.
The awesome part of it was that I learned quite a’lot about how both EPiServer Find and the new pluggable runtime cache in EPiServer 7.5 works. I’ll save the pluggable runtime cache in EPiServer CMS 7.5 for a later post and share my findings (pun! score!) on EPiServer Find here.
Instead let’s take a look at the two culprits in my cache-endeavor: GetResult and GetContentResult in EPiServer Find.
First of all GetResult in EPiServer Find isn’t cached by default. Think of it as a method to get data from EPiServer Find that probably doesn’t have any sort of connection to data stored in EPiServer CMS. This method doesn’t tie into the EPiServer API as GetContentResult does. It’s more native ElasticSearch than anything else.
Getting a YSOD when using GetResult for content data? It’s probably because content types are rather complex types, and it’s difficult to parse from the JSON-format. What you need to do is project it using a select-operation. E.g.
var result = client.Search<ArticlePage>()
.Select(x => x.ContentReference)
This is not a recommended approach for a number of reasons. Read on to discover why.
Here’s where things get interesting. Thought that GetContentResult returned all your content data over the wire? It doesn’t. In fact, it’s quite clever: it fetches the IDs of the content that match your query and serves them back. With the IDs it queries EPiServer’s data layer APIs to fetch the data. Meaning it benefits from all the cache logic that’s built-in with the EPiServer CMS framework. Should the editor update their content it’s ejected from the cache and with the next EPiServer Find query you’ll get some steaming hot fresh data served up. Also, the data passed over the wire is kept to a minimum. Awesome job, EPiServer Find team!
EPiServer Find can also “statically” cache a query, and this would be outside the scope of the EPiServer CMS data layer API. It does, however, not cache the entire content object instead just the content IDs the query results in.
Wrapping it up
So what’s the key takeaway from this? If you have complex operations on your website that work with a’lot of data, e.g. news, contact or calendar list with filtering you should be using EPiServer Find. Your queries using GetContentResult would be lightning fast and you can always trust that your data will be cached and up to date without yourself adding compex cache layers to the solution.
While EPiServer Find has an 99.95% uptime, you should make sure that the website doesn’t break if the EPiServer Find service is unavailable. Maybe even implement a fallback.
If you use GetContent for data that is outside the EPiServer data layer APIs you may want to invest some time into adding your own caching mechanisms for the data returned.
With this I hope you’ll come to love EPiServer Find even more and utilize it to build some fantastic solutions with your website.