Optimizing LINQ Query Performance
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 therefore 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 example, 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 example, 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’ll no longer be able to access specific fields on search results.
For example, if you have the following query:
using (var context = ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext()) {
return context.GetQueryable<SearchResultItem>().Take(1000).ToList();
}
You couldn’t access result["mySpecificField"]
on a single result, as mySpecificField
wouldn’t be present on results.
You can easily specify those extra fields by creating your own processor (see Understanding the coveoPostItemProcessingPipeline
Pipeline).
For example, 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>