Foreign Keys and Computed Fields in Coveo for Sitecore

Posted 07/29/2014 by Akshay Sura

Coveo JS Framework allows us to deploy search pages with minimal coding. Most of the functionality can be achieved via configuration from the page/content editor. Eventually you would need to add in facets or fields that require you to define relationships between templates. For instance a News items has News Categories, and while displaying the News items in the search we would also like to display the category/categories the news item belongs to.

To achieve this functionality, we can use Foreign Keys. There is some documentation on the Coveo website at this Link. Foreign Keys are pretty straight forward, we need to know the parent/main Template, in our case its News and the Field (guid(s)), which link to the child template, which is News Categories. We then need the child template, which is News Category, and its ID and Value fields, id and Category Name respectively.

Knowing the above, you would add it to your custom config, here is a sample:

  
    
      
        
          
            
              
                
                  News

News Categories News Category id Category Name

Foreign Keys work great, they do not increase the indexing time but are not suitable in a multilingual scenario. For a site running on multiple languages you would need to use computed fields or modify the REST pipeline to get the values in the context language. We will cover the REST pipeline for Coveo in future posts.

Creating a computed field is very easy and you can find some documentation on the Coveo website at this Link.  

A computed field allows us to store a computed/calculated value in an additional field in the index. So for instance if you are storing products, we can have a computed field which automatically calculates the shipping cost based on the product weight and dimensions and stores it. This way the UI does not have to do this calculation.

Similarly, in a multilingual scenario, we can use the computed field to store the language specific value(s) for foreign key relationships.

Here is an example of a computed field that clears any html from a summary field and stores it in the index for display purposes:

using Sitecore;
using Sitecore.ContentSearch;
using Sitecore.ContentSearch.ComputedFields;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace YOURNAMESPACE.ComputedFields
{
    //computed field to strip html from the summary field.
    public class CleanSummaryField : IComputedIndexField
    {
        public object ComputeFieldValue(Sitecore.ContentSearch.IIndexable p_Indexable)
        {
                        //get the field from the item which needs to be processed
            IIndexableDataField field = p_Indexable.GetFieldByName("Summary");
            var value = string.Empty;

            //check if the summary field is not null and has a value
            if (field != null && !string.IsNullOrEmpty(field.Value.ToString()))
            {
                var nonClean = field.Value.ToString();

                //use html agility pack to load the document and get just text
                var doc = new HtmlAgilityPack.HtmlDocument();
                doc.LoadHtml(nonClean);
                                
                value = doc.DocumentNode.InnerText;
            }

            return value;
        }

        public string FieldName { get; set; }
        public string ReturnType { get; set; }
    }
}

Here is the sample configuration in your custom config:

  
    
      
        
          
            Sitecore.ContentSearch.ComputedFields.AllTemplates, Sitecore.ContentSearch

YOURNAMESPACE.ComputedFields.CleanSummaryField, YOURNAMESPACE