In some of our critical pieces of implementation revolving around Coveo renderings, due to our heavy hierarchical data for SEO benefit, we had multiple situations where we were having computed fields that read a piece of data from direct or in-direct parent of the current item in question in sitecore.
It was working out perfectly, no additional load time or performance issue as indexing operation should fully load what we need on the current sitecore item. Until!!!
Recently, I ran in to this situation where say you have the whole hierarchical data already in play, which just means we did not create a child and did not publish the current item. But, a scenario where a field that you are reading in computed field from parent actually changed. In this situation, due to inherent behavior of how indexing would work, the parent would be re-indexed(As that is the item that is changed and hence added to delta by Coveo). Now, we have child having an outdated computed field which in index memory still has stale data until you force build indexes or publish the child.
In real life scenario, you would take an item through workflow, in this case parent is changed, so it would enter the Sitecore workflow and will be pushed live. But, in our case, every time a parent changes, we want the children also to re-index, so, we do not have situation of out-of-sync data.
So, additional configuration would be needed every time you have a scenario where a computed field say depends on some other item (like parent in our case or it could be something else in the sitecore tree as well). To address this and ensure it works as expected in ideal scenario, we need to do below steps
1. Patch to coveoItemProcessingPipeline and add a new processor - call it say 'RelatedItemsPreProcessor'
2. Implement what happens in the processor, in our case we had to get all children and add it to List of items that Coveo re-indexes when this specific item is in delta. Quick example below, it could be changed per your needs. There is a basic example on Coveo documentation as well.
public class RelatedItemsPreProcessor : IProcessor<CoveoItemProcessingPipelineArgs>
{
public void Process(CoveoItemProcessingPipelineArgs p_Args)
{
SitecoreIndexableItem indexableItem = p_Args.Item as SitecoreIndexableItem;
if(indexableItem != null)
{
Item item = indexableItem.Item;
if(item.TemplateID.Guid.Equals(yourguidgoeshere))
{
if(item.HasChildren)
{
//Get all children using query
string query = string.Format("descendant - or - self::*[@@templateid = '{0}' ]", YourGUID);
var childrenOfItem = item.Axes.SelectItems(query);
if(childrenOfItem != null && childrenOfItem.Any())
{
foreach(var itm in childrenOfItem)
{
//Add the item to the output list
var itemToBeAdded = new SitecoreIndexableItem(itm);
if (!p_Args.OutputItems.Contains(itemToBeAdded))
p_Args.OutputItems.Add(new SitecoreIndexableItem(itm));
}
}
}
}
3. Add this new processor in your Coveo.SearchProvider.Custom.config
<coveoItemProcessingPipeline>
<processor type="namespace.RelatedItemsPreProcessor, Extensions" />
</coveoItemProcessingPipeline>
That is it! Post this simple steps, I can be rest assured that our data integrity would be in place post the workflow is implemented. It is really easy to miss this in your implementation when most of your users are logging in using admin credentials for example and probably publishing sub-items every time they publish a change. Keep an eye open for these kind of situations.
Review pipeline's available here https://developers.coveo.com/display/public/SitecoreV3/Understanding+the+Indexing+and+Search+Pipelines;jsessionid=814B71D25E05C8684E2C029CEC416070
It was working out perfectly, no additional load time or performance issue as indexing operation should fully load what we need on the current sitecore item. Until!!!
Recently, I ran in to this situation where say you have the whole hierarchical data already in play, which just means we did not create a child and did not publish the current item. But, a scenario where a field that you are reading in computed field from parent actually changed. In this situation, due to inherent behavior of how indexing would work, the parent would be re-indexed(As that is the item that is changed and hence added to delta by Coveo). Now, we have child having an outdated computed field which in index memory still has stale data until you force build indexes or publish the child.
In real life scenario, you would take an item through workflow, in this case parent is changed, so it would enter the Sitecore workflow and will be pushed live. But, in our case, every time a parent changes, we want the children also to re-index, so, we do not have situation of out-of-sync data.
So, additional configuration would be needed every time you have a scenario where a computed field say depends on some other item (like parent in our case or it could be something else in the sitecore tree as well). To address this and ensure it works as expected in ideal scenario, we need to do below steps
1. Patch to coveoItemProcessingPipeline and add a new processor - call it say 'RelatedItemsPreProcessor'
2. Implement what happens in the processor, in our case we had to get all children and add it to List of items that Coveo re-indexes when this specific item is in delta. Quick example below, it could be changed per your needs. There is a basic example on Coveo documentation as well.
public class RelatedItemsPreProcessor : IProcessor<CoveoItemProcessingPipelineArgs>
{
public void Process(CoveoItemProcessingPipelineArgs p_Args)
{
SitecoreIndexableItem indexableItem = p_Args.Item as SitecoreIndexableItem;
if(indexableItem != null)
{
Item item = indexableItem.Item;
if(item.TemplateID.Guid.Equals(yourguidgoeshere))
{
if(item.HasChildren)
{
//Get all children using query
string query = string.Format("descendant - or - self::*[@@templateid = '{0}' ]", YourGUID);
var childrenOfItem = item.Axes.SelectItems(query);
if(childrenOfItem != null && childrenOfItem.Any())
{
foreach(var itm in childrenOfItem)
{
//Add the item to the output list
var itemToBeAdded = new SitecoreIndexableItem(itm);
if (!p_Args.OutputItems.Contains(itemToBeAdded))
p_Args.OutputItems.Add(new SitecoreIndexableItem(itm));
}
}
}
}
3. Add this new processor in your Coveo.SearchProvider.Custom.config
<coveoItemProcessingPipeline>
<processor type="namespace.RelatedItemsPreProcessor, Extensions" />
</coveoItemProcessingPipeline>
That is it! Post this simple steps, I can be rest assured that our data integrity would be in place post the workflow is implemented. It is really easy to miss this in your implementation when most of your users are logging in using admin credentials for example and probably publishing sub-items every time they publish a change. Keep an eye open for these kind of situations.
Review pipeline's available here https://developers.coveo.com/display/public/SitecoreV3/Understanding+the+Indexing+and+Search+Pipelines;jsessionid=814B71D25E05C8684E2C029CEC416070