Coveo for Sitecore 5 is now available!

Optimizing LINQ Query Performance

Coveo for Sitecore 4.1 (November 2018)

If you’re experiencing poor performances with your LINQ queries and Coveo, you can fine-tune a few pipelines to make them faster. By default, LINQ queries return all fields on your documents, which is often not needed.

Option 1: Do Not Index the Coveo Fields on Documents

As explained in Understanding the Coveo Search Provider’s Configuration File, there’s a parameter named indexCoveoFields in the Coveo.SearchProvider.config file.

This parameter is true by default, but you can set it to false and then re-index your documents. This removes a lot of fields from your documents, and thus makes search results lighter.

Remember that, to avoid upgrading issues or unexpected bugs, you should perform your modifications in the Coveo.SearchProvider.Custom.config file instead of the Coveo.SearchProvider.config file.

Limitations

If you were using any of those fields on layouts/rules, they won’t be available anymore, so you must adjust them to use Sitecore fields instead.

For instance, if you were using fields such as name or templatename, you should instead use _name or _templatename.

Option 2: Optimizing the coveoQueryFieldPipeline

This pipeline is used to specify which fields should be returned in LINQ query results. It returns all fields by default.

Open your Coveo.SearchProvider.Custom.config file and search for the following lines.

<coveoQueryFieldPipeline>
  <!--
    <processor type="Coveo.SearchProvider.Processors.Queries.AddAllFieldsProcessor, Coveo.SearchProviderBase">
      <patch:delete />
    </processor>
    <processor type="Coveo.SearchProvider.Processors.Queries.AddBasicFieldsProcessor, Coveo.SearchProviderBase" />
    <processor type="Coveo.SearchProvider.Processors.Queries.AddVirtualFieldsProcessor, Coveo.SearchProviderBase" />
    <processor type="Coveo.SearchProvider.Processors.Queries.AddFieldsRelatedToSearchTypeProcessor, Coveo.SearchProviderBase" />
  -->
</coveoQueryFieldPipeline>

You can see that by default, only the AddAllFieldsProcessor processor is enabled from the Coveo.SearchProvider.config file. You can uncomment this block in the Coveo.SearchProvider.Custom.config file to disable the AddAllFieldsProcessor processor and enable the other processors instead if you want to improve performances.

Your configuration should then look like this:

<coveoQueryFieldPipeline>
    <processor type="Coveo.SearchProvider.Processors.Queries.AddAllFieldsProcessor, Coveo.SearchProviderBase">
      <patch:delete />
    </processor>
    <processor type="Coveo.SearchProvider.Processors.Queries.AddBasicFieldsProcessor, Coveo.SearchProviderBase" />
    <processor type="Coveo.SearchProvider.Processors.Queries.AddVirtualFieldsProcessor, Coveo.SearchProviderBase" />
    <processor type="Coveo.SearchProvider.Processors.Queries.AddFieldsRelatedToSearchTypeProcessor, Coveo.SearchProviderBase" />
</coveoQueryFieldPipeline>

AddBasicFieldsProcessor

This processor specifies that a few basic fields should be returned. Those fields are:

  • id
  • _id
  • _uniqueid
  • _language
  • _latestversion

AddVirtualFieldsProcessor

This processor specifies that fields needed for the virtual fields processor should be returned in the query.

AddFieldsRelatedToSearchTypeProcessor

This processor loads the properties of the LINQ search type by reflection to add them in the list of desired fields.

For instance, if you’re querying for a Sitecore SearchResultItem, it will load all its properties to add them to the list.

Limitations

Not returning all fields of documents has one limitation; you will no longer be able to access specific fields on search results.

For instance, if you have the following query:

using (var context = ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext()) {
    return context.GetQueryable<SearchResultItem>().Take(1000).ToList();
}

You could not access result["mySpecificField"] on a single result, as mySpecificField would not be present on results.

You can easily specify those extra fields by creating your own processor (see Example Processor Using the coveoPostItemProcessingPipeline Pipeline).

For instance, if you want mySpecificField to be returned within the fields of search results, you would need to insert this code:

using System.Reflection;
using Coveo.AbstractLayer.FieldManagement;
using Coveo.Framework.CNL;
using Coveo.Framework.Log;
using Coveo.Framework.Processor;
using Coveo.SearchProvider.Pipelines;
using Sitecore.ContentSearch;
namespace Sample
{
    public class AddSpecifiedFieldProcessor : IProcessor<CoveoQueryFieldPipelineArgs>
    {
        public void Process(CoveoQueryFieldPipelineArgs p_Args)
        {
            p_Args.FieldNames.Add("mySpecificField");
        }
    }
}

And then add this new processor to the configuration:

<coveoQueryFieldPipeline>
    <processor type="Coveo.SearchProvider.Processors.Queries.AddAllFieldsProcessor, Coveo.SearchProviderBase">
      <patch:delete />
    </processor>
    <processor type="Coveo.SearchProvider.Processors.Queries.AddBasicFieldsProcessor, Coveo.SearchProviderBase" />
    <processor type="Coveo.SearchProvider.Processors.Queries.AddVirtualFieldsProcessor, Coveo.SearchProviderBase" />
    <processor type="Coveo.SearchProvider.Processors.Queries.AddFieldsRelatedToSearchTypeProcessor, Coveo.SearchProviderBase" />
    <processor type="Sample.AddSpecificFieldProcessor, Sample" />
</coveoQueryFieldPipeline>
Recommended Articles