Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sitecore Lucene: re-index child (or parent) items on updating item

Situation

I have the following Sitecore Lucene config:

  • New index, type="Sitecore.Search.Index, Sitecore.Kernel"
  • Contains two crawlers (a custom crawler that adds extra "calculated" fields)
  • Each crawler handles its specific template GUID, because they contain different calculated fields

Problem

The calculated fields are based on parent/child fields. How Lucene in Sitecore seems to be set up, is that only the documents for the items that were actually changed are updated in the index.

As such, the calculated fields on other documents (which are required, there are search conditions on these fields) are not updated.

Question

Is there a possibility to manually trigger the update of other items in the index?
I've looked into inheriting Sitecore.Search.Index, but none of the relevant methods are virtual.

Also, I tried to subscribe to the IndexingProvider-events:
public event EventHandler OnRemoveItem;
public event EventHandler OnRemoveVersion;
public event EventHandler OnUpdateItem;

The idea behind this was to trigger the OnUpdateItem-event in the DatabaseCrawler for other items that need to be updated, but you can't trigger this event from outside the IndexingProvider.

Is there a way to trigger an index update without doing a full rebuild, that does not involve saving/republishing those other items?

Thanks!
Sander

like image 992
sanderd Avatar asked Nov 24 '11 09:11

sanderd


1 Answers

The Index update is triggered via the HistoryEngine, whose events and methods are public, so you could potentially utilize an event handler on the history engine to detect when a change occurs that requires reindexing, and then add additional entries to the history for the parent/child items you need to reindex as well.

Sitecore.Data.Managers.IndexingManager.InitializeEventHandlers() has an example of attaching a handler to the HistoryEngine of the databases.

Then your handler logic would be something like

protected void HistoryEngine_AddedEntry(object sender, HistoryAddedEventArgs e)
{
    Item item = e.Database.GetItem(e.Entry.ItemId);
    //TODO: Add logic to make sure e.Entry.ItemId requires a parent/child reindex as well
    //TODO: Make sure that logic also prevents excessive or infinite recursion since we'll be triggering the AddedEntry event again below
    Item parent = item.Parent;
    //RegisterItemSaved doesn't appear to do anything with its second argument
    e.Database.Engines.HistoryEngine.RegisterItemSaved(parent, null);
}

The best place to attach this is probably in the initialize pipeline.

N.B. this is an untested idea, please report back on your results!

like image 171
nickwesselman Avatar answered Oct 14 '22 10:10

nickwesselman