Updated: March 4, 2015
Recently, I’ve been working on a big website which has a lot of content. On it, we’ve been indexing custom properties for Examine to search against. I’ve outlined how to do this below – implement IApplicationEventHandler and hook into Examine's GatheringNodeData events on application startup:
public class AppEvents : IApplicationEventHandler { public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) { } public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) { } public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) { ExamineManager.Instance.IndexProviderCollection["ContentIndexer"].GatheringNodeData += ExamineEvents.GatheringContentData; } } public static class ExamineEvents { public static void GatheringContentData(object sender, IndexingNodeDataEventArgs e) { // BAD - DON'T DO THIS! var content = ApplicationContext.Current.Services.ContentService.GetById(e.NodeId); // Custom indexing logic if (content.ContentType.Alias == "CollectionPage") { e.Fields.Add("types", "1"); e.Fields.Add("typeNames", "Collection"); } } }
But this approach is seriously flawed - using ContentService.GetById means numerous calls are made to the database, and this is incredibly slow (on the site I've been working on, re-indexing was taking several minutes!). This approach is popular because there is no access to UmbracoContext in the event handlers. However, as shown below, you can pass in the UmbracoHelper when hooking up to GatheringNodeData. This makes calls to the Umbraco XML cache instead, cutting indexing time to just a few seconds.
public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) { var helper = new UmbracoHelper(UmbracoContext.Current); ExamineManager.Instance.IndexProviderCollection["ContentIndexer"].GatheringNodeData += (sender, e) => ExamineEvents.GatheringContentData(sender, e, helper); } public static void GatheringContentData(object sender, IndexingNodeDataEventArgs e, UmbracoHelper helper) { var content = helper.TypedContent(e.NodeId); // Custom indexing logic if (content.ContentType.Alias == "CollectionPage") { e.Fields.Add("types", "1"); e.Fields.Add("typeNames", "Collection"); } }