Engineering · Sitecore

On Sitecore item publish, update a single record in the index

Recently we faced an interesting problem. We were updating a Sitecore item field, but after publishing, the change was not reflected in the search results, which come from the index. Rebuilding the index updated it, but we have thousands of items in the index and a full rebuild takes a long time. Our challenge: update a Sitecore item, publish it, and see the change in the index without rebuilding the whole thing.

There are many ways to solve this, but we followed two simple steps. First, we worked out how to update a single record in the index. Second, we ran that update whenever the Sitecore item is published.

In the back end, we get the Sitecore item from Context, and from the item, we get the SitecoreItemUniqueId. Then we get the index using ContentSearchManager. Now, update the record in the index by calling IndexCustodian.UpdateItem.

var item = context.PublishOptions.TargetDatabase.GetItem(context.ItemId);
var uniqueId = new SitecoreItemUniqueId(item?.Uri);
var webContentIndex = ContentSearchManager.GetIndex(IndexName);

IndexCustodian.UpdateItem(webContentIndex, uniqueId);
.

Every time we do a publish in Sitecore, it executes an event named “publish:itemProcessed”. We implement a handler and hook into this event. The handler runs the code above and updates a single index record each time we update and publish an item. Handler code:

namespace XYZ.Foundation.Indexing.Events
{
    public class ItemProcessedProcessor
    {
        public void ItemProcessed(object sender, EventArgs args)
        {
            ItemProcessedEventArgs itemProcessedEventArgs = args as ItemProcessedEventArgs;
            PublishItemContext context = itemProcessedEventArgs != null ? itemProcessedEventArgs.Context : null;
		}
	}
}

Here is the Sitecore patch for the event handler:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
	<sitecore>
		<events>
			<event name="publish:itemProcessed">
				<handler type="XYZ.Foundation.Indexing.Events.ItemProcessedProcessor, XYZ.Foundation.Indexing" method="ItemProcessed"/>
			</event>
		</events>
	</sitecore>
</configuration>

Thanks
Munir