Ultra fast media performance in Umbraco

There’s a few different ways to query Umbraco for media: using the new Media(int) API , using the umbraco.library.GetMedia(int, false) API or querying for media with Examine. I suppose there’s quite a few people out there that don’t use Examine yet and therefore don’t know that all of the media information is actually stored there too! The problem with the first 2 methods listed above is that they make database queries, the 2nd method is slightly better because it has built in caching, but the Examine method is by far the fastest and most efficient.

The following table shows you the different caveats that each option has:

new Media(int)

library.GetMedia(int,false)

Examine

Makes DB calls

yes

yes

no

Caches result

no

yes

no

Real time data

yes

yes

no

You might note that Examine doesn’t cache the result whereas the GetMedia call does, but don’t let this fool you because the Examine searcher that returns the result will be nearly as fast as ‘In cache’ data but won’t require the additional memory that the GetMedia cache does. The other thing to note is that Examine doesn’t have real time data. This means that if an administrator creates/saves a new media item it won’t show up in the Examine index instantaneously, instead it may take up to a minute to be ingested into the index. Lastly, its obvious that the new Media(int) API isn’t a very good way of accessing Umbraco media because it makes a few database calls per media item and also doesn’t cache the result.

Examine would be the ideal way to access your media if it was real time, so instead, we’ll combine the efforts of Examine and library.GetMedia(int,false) APIs. First will check if Examine has the data, and if not, revert to the GetMedia API. This method will do this for us and return a new object called MediaValues which simply contains a Name and Values property:

First here’s the usage of the new API below:

var media = MediaHelper.GetUmbracoMedia(1234); var mediaFile = media["umbracoFile"];

That’s a pretty easy way to access media. Now, here’s the code to make it work:

public static MediaValues GetUmbracoMedia(int id) { //first check in Examine as this is WAY faster var criteria = ExamineManager.Instance .SearchProviderCollection["InternalSearcher"] .CreateSearchCriteria("media"); var filter = criteria.Id(id); var results = ExamineManager .Instance.SearchProviderCollection["InternalSearcher"] .Search(filter.Compile()); if (results.Any()) { return new MediaValues(results.First()); } var media = umbraco.library.GetMedia(id, false); if (media != null && media.Current != null) { media.MoveNext(); return new MediaValues(media.Current); } return null; }

 

The MediaValues class definition:

public class MediaValues { public MediaValues(XPathNavigator xpath) { if (xpath == null) throw new ArgumentNullException("xpath"); Name = xpath.GetAttribute("nodeName", ""); Values = new Dictionary<string, string>(); var result = xpath.SelectChildren(XPathNodeType.Element); while(result.MoveNext()) { if (result.Current != null && !result.Current.HasAttributes) { Values.Add(result.Current.Name, result.Current.Value); } } } public MediaValues(SearchResult result) { if (result == null) throw new ArgumentNullException("result"); Name = result.Fields["nodeName"]; Values = result.Fields; } public string Name { get; private set; } public IDictionary<string, string> Values { get; private set; } }

That’s it! Now you have the benefits of Examine’s ultra fast data access and real-time data in case it hasn’t made it into Examine’s index yet.

Author

Administrator (1)

comments powered by Disqus