Coveo for Sitecore 5 is now available!

Adding Processors to Indexing and Search Pipelines

Here is a list of processors that you can add to your pipelines to perform various tasks.

Adding a Processor to coveoItemProcessingPipeline

The following code sample shows you how to index a Sitecore item along with its related items. You will most likely need to adapt this code sample to make it work in your own environment.

using Coveo.Framework.Processor;
using Coveo.SearchProvider.Pipelines;
using Sitecore.ContentSearch;
using Sitecore.Data.Fields;
using Sitecore.Data.Items;
namespace Coveo.Demos.Pipelines
{
    public class RelatedItemPreProcessor : IProcessor<CoveoItemProcessingPipelineArgs>
    {
        public void Process(CoveoItemProcessingPipelineArgs p_Args)
        {
            // In this example, our goal is to retrieve the media item related to the item being currently processed, and index it along with the current item.
            // The template of the current item contains a field named 'MediaItem' of type 'Droptree' which points to a specific item located in the media library.
            List<IIndexable> itemsToAdd = new List<IIndexable>();
            // We operate on the indexables in p_Args.OutputItems in case previous processors added new items
            foreach (IIndexable indexableItem in p_Args.OutputItems) {
                SitecoreIndexableItem sitecoreIndexableItem = indexableItem as SitecoreIndexableItem;
                IIndexableBuiltinFields builtInFields = sitecoreIndexableItem;
                if (sitecoreIndexableItem != null) {
                    Item item = sitecoreIndexableItem.Item;
                    // If the item being currently processed is of the expected type (template = 'Sample Item V2'), we process it.
                    if (builtInFields.TemplateId.ToString().Equals("{41013191-AB12-4074-BFF0-3861AA2148AC}")) {
                        // Since this is a pre-processor, the Coveo Search Provider has not yet processed the current item, so we only have the raw Sitecore item (i.e., SitecoreIndexableItem)
                        // in our hands.
                        //
                        // Here, we retrieve the related media library item and we append it to the list of output items.
                        // p_Args.OutputItem already contains the original item.
                        Field mediaItemField = item.Fields["MediaItem"];
                        Sitecore.Data.Database database = Sitecore.Configuration.Factory.GetDatabase(builtInFields.Database);
                        Item relatedMediaItem = database.GetItem(mediaItemField.Value);
                        itemsToAdd.Add(new SitecoreIndexableItem(relatedMediaItem));
                    }
                }
            }
            p_Args.OutputItems.AddRange(itemsToAdd);
        }
    }
}

Adding a Processor to coveoPostItemProcessingPipeline

The following code sample shows you how to index entirely virtual items (i.e., items that don’t really exist in Sitecore) based on existing items. Again, you will need to adapt this code sample to make it work in your own environment.

using System.Collections.Generic;
using Coveo.AbstractLayer.RepositoryItem;
using Coveo.Framework.Processor;
using Coveo.SearchProvider.Pipelines;
using Sitecore.ContentSearch;
using Sitecore.Data.Fields;
using Sitecore.Data.Items;
namespace Coveo.Demos.Pipelines
{
    public class TranslatedItemPostProcessor : IProcessor<CoveoPostItemProcessingPipelineArgs>
    {
        public void Process(CoveoPostItemProcessingPipelineArgs p_Args)
        {
            // In this example, our goal is to manually translate a specific item from English to French, and index its translated version as a separate item.
            List<CoveoIndexableItem> itemsToAdd = new List<CoveoIndexableItem>();
            // We operate on the indexables in p_Args.CoveoOutputItems in case previous processors added new items. A reference to the original item is already in this list
            foreach (CoveoIndexableItem coveoIndexableItem in p_Args.OutputCoveoItems) {
                SitecoreIndexableItem indexableItem = p_Args.Item as SitecoreIndexableItem;
                IIndexableBuiltinFields builtInFields = indexableItem;
                if (indexableItem != null) {
                    Item item = indexableItem.Item;
                    // If the item being currently processed is of the expected type (template = Sample Item), we process it.
                    if (builtInFields.TemplateId.ToString().Equals("{76036F5E-CBCE-46D1-AF0A-4143F9B557AA}")) {
                        // If the 'Text' field has the expected value, it means that the current item is indeed the one that we are interested in.
                        Field textField = item.Fields["Text"];
                        if (textField.Value == "<p>This is a test!</p>") {
                            // The value of the original item's UniqueId property has the following format: sitecore://{database}/{item_id}?lang={language}&ver={version}.
                            // But our new item must have a different UniqueId value to be indexed by Coveo, so we change the values of its language and version parameters.
                            string newUniqueId = coveoIndexableItem.UniqueId.Replace("lang=en", "lang=fr").Replace("ver=1", "ver=2");
                            // To create a new item, we clone the original one and we change the properties and values that we are interested in.
                            CoveoIndexableItem newItem = new CoveoIndexableItem {
                                BinaryData = coveoIndexableItem.BinaryData,
                                BinaryDataMimeType = coveoIndexableItem.BinaryDataMimeType,
                                BinaryDataPath = coveoIndexableItem.BinaryDataPath,
                                ClickableUri = coveoIndexableItem.ClickableUri,
                                FileName = coveoIndexableItem.FileName,
                                HasSubItems = coveoIndexableItem.HasSubItems,
                                Id = coveoIndexableItem.Id,
                                IsDeletedItem = coveoIndexableItem.IsDeletedItem,
                                ModifiedDate = coveoIndexableItem.ModifiedDate,
                                Parent = coveoIndexableItem.Parent,
                                ParentId = coveoIndexableItem.ParentId,
                                Path = coveoIndexableItem.Path,
                                Permissions = coveoIndexableItem.Permissions,
                                PrintablePath = coveoIndexableItem.PrintablePath,
                                Title = "Item Exemple",
                                UniqueId = newUniqueId,
                                Metadata = new Dictionary<string, object>(coveoIndexableItem.Metadata)
                            };
                            // Here, we:
                            // -Manually translate the original title to French.
                            // -Change the value of a few metadata fields to reflect the differences in our translated item.
                            newItem.SetMetadata("Text", "Ceci est un test!");
                            newItem.SetMetadata("Language", "fr");
                            newItem.SetMetadata("Languages", "fr");
                            newItem.SetMetadata("Version", "2");
                            // Since we are using a post-processing pipeline, computed fields such as ParsedLanguage have already been processed.
                            // So here we change its value to 'french'.
                            newItem.SetMetadata("parsedlanguage", "french");
                            // OutputCoveoItems always contains the original item as its first item. It's actually the same instance of CoveoIndexableItem as in p_Args.CoveoItem, so if you want to
                            // modify the original item, you can do it either through p_Args.CoveoItem or p_Args.OutputCoveoItems. We add the new item to the output items.
                            itemsToAdd.Add(newItem);
                        }
                    }
                }
            }
            p_Args.OutputCoveoItems.AddRange(itemsToAdd);
        }
    }
}

Adding a Processor to coveoBeforeUpdateFieldSetPipeline

The following code sample shows you how to pre-process Sitecore fields before they’re added to a Coveo field set. The NumericField1 field comes from some Sitecore template; Coveo makes it facetable. Again, you will need to adapt this code sample to make it work in your own environment.

using System;
using System.Collections.Generic;
using System.Linq;
using Coveo.AbstractLayer.Pipeline;
using Coveo.Framework.Fields.Config;
using Coveo.Framework.Processor;
namespace Coveo.Demos.Pipelines
{
    public class BeforeUpdateFieldSetProcessor : IProcessor<CoveoBeforeUpdateFieldSetPipelineArgs>
    {
        public void Process(CoveoBeforeUpdateFieldSetPipelineArgs p_Args)
        {
            // If the index being currently processed is the one associated with the 'master' database, then we process the numeric field.
            if (p_Args.IndexName == "sitecore_master_index") {
                SetNumericFieldsAsFacet(p_Args.Fields);
            }
        }
        private void SetNumericFieldsAsFacet(IEnumerable<FieldConfig> p_Fields)
        {
            // Here, we get the 'NumericField1' field (which is of type 'Number') and we set it as a facet, so that we'll be able to create a Coveo Facet component based on it.
            // This is the same thing as setting the field facetable directly through the Coveo Search Provider's configuration file (isFacet="true").
            // This code is executed just before the Fields Set is processed by the Coveo Search Provider. 
            FieldConfig fieldConfig = p_Fields.FirstOrDefault(field => String.Equals(field.SitecoreFieldName, "NumericField1", StringComparison.InvariantCultureIgnoreCase));
            if (fieldConfig != null) {
                fieldConfig.IsFacet = true;
            }
        }
    }
}

Adding a Processor to indexing.filterIndex.inbound

The following code sample shows you how to filter out items from your search indexes. In this case, the items named __Standard Values are excluded. Normally, you won’t need to adapt this code sample to make it work in your own environment.

using System;
using Sitecore.ContentSearch;
using Sitecore.ContentSearch.Pipelines.IndexingFilters;
namespace Coveo.Demos.Pipelines
{
    public class ExcludeStandardValuesItemsProcessor : InboundIndexFilterProcessor
    {
        public override void Process(InboundIndexFilterArgs args)
        {
            // Here, we check whether the item being currently processed is a 'Standard Values' item. If so, we prevent it
            // from being indexed in the current search index.
            SitecoreIndexableItem item = args.IndexableToIndex as SitecoreIndexableItem;
            if (String.Equals(item.Item.Name, "__Standard Values", StringComparison.InvariantCultureIgnoreCase)) {
                args.IsExcluded = true;
            }
        }
    }
}

Using the coveoInboundFilterPipeline

The advantage of using this pipeline over the Sitecore indexing.filterIndex.inbound pipeline is that its filters can be applied to specific Coveo indexes. In other words, indexes can be included or excluded from a processor scope.

By default, a processor defined in this pipeline is applied to all Coveo indexes. To apply a processor only to specific indexes, specify those indexes name under a includedIndexNames node as follows.

<processor type="Coveo.SearchProvider.InboundFilters.ApplySitecoreInboundFilterProcessor, Coveo.SearchProviderBase">
  <includedIndexNames hint="list">
    <indexName>Coveo_web_index</indexName>
  </includedIndexNames>
</processor>

To apply a processor to all but some specific indexes, specify those index names under a excludedIndexNames node as follows.

<processor type="Coveo.SearchProvider.InboundFilters.ApplySitecoreInboundFilterProcessor, Coveo.SearchProviderBase">
  <excludedIndexNames hint="list">
    <indexName>Coveo_master_index</indexName>
  </excludedIndexNames>
</processor>

If an index is specified in both lists, the filter won’t be applied to this index.

Adding a Processor to coveoInboundFilterPipeline

The following code sample shows how you can filter out items from your search indexes. In this case, the items named __Standard Values are excluded. Normally, you won’t need to adapt this code sample to make it work in your own environment.

using Coveo.Framework.Items;
using Coveo.SearchProvider.Pipelines;
namespace Coveo.Demos.Pipelines
{
    public class ExcludeStandardValuesItemsProcessor : AbstractCoveoInboundFilterProcessor
    {
        public override void Process(CoveoInboundFilterPipelineArgs args)
        {
            // The ShouldExecute(CoveoInboundFilterPipelineArgs) tests whether the code should be executed.
            // It will return false if p_Args.IsExcluded is true or if the current index is excluded.
            if (ShouldExecute(p_Args)) {
                // Here, we check whether the item being currently processed is a 'Standard Values' item. If so, we prevent it
                // from being indexed in the current search index.
                IIndexableWrapper item = args.IndexableToIndex;
                if (String.Equals(item.Item.Name, "__Standard Values", StringComparison.InvariantCultureIgnoreCase)) {
                    args.IsExcluded = true;
                }
            }
        }
    }
}

Adding a Processor to getSearchUserIdentities

Coveo for Sitecore (June 2016)

The following code sample shows how to add a static identity to a user using the Coveo.SearchProvider.Rest.Processors.GetSearchUserIdentities.AddIdentity processor. You must add this code snippet in the Coveo.SearchProvider.Custom.config file.

<getSearchUserIdentities>
    <processor type="Coveo.SearchProvider.Rest.Processors.GetSearchUserIdentities.AddIdentity">
        <identityName><!-- Put the identity name here --></identityName>
        <identityType><!-- Put the identity type here --></identityType>
        <securityProviderName><!-- Put the security provider name here --></securityProviderName>
    </processor>
</getSearchUserIdentities>

In identityName, you should set the identity name that you want to pass (e.g., sitecore\john.smith ; john.smith@local.net).

In identityType, you should set the type of the identity that you want to pass (e.g., user ; group).

In securityProviderName, you should set the name of the security provider you want to use to handle these identities (e.g., Email Security Provider).

This processor won’t work if you want to map a Sitecore user to another identity. To learn how to do this, see Creating a Processor for the getSearchUserIdentities Pipeline.

What's Next for Me?