Sitecore Coveo free edition using rules engine to filter result

Before reading please be aware that the rules are disabled in the Free edition because they are part of the Ranking Editor feature sold in the Enterprise edition. Using them to look up how queries look like with the Free edition is OK if you then use them like this http://goo.gl/oVeV6Z. But, you cannot give this feature to the End Customer with the Free edition.

Site search is an important part of functionality from a website, some website even make their main navigation functionality for site visitors – think of airlines or eCommerce website.

Sitecore has a couple of options to built a site search functionality which can be achieved by using Lucene and SOLR. There’s another option which is using Coveo, an enterprise search provider that has an integration module with Sitecore. Recently Coveo released the free edition for Sitecore which I decided to try out.

I was impressed by the result, I particularly like how easy it is to set it up given that Coveo has predefined renderings that’s ready to use. I literally just create a new page with Coveo search result layout with it’s predefined renderings, add some new renderings to give the search result page some specific filter, and sorting functionality. It just works.

All looks good so far but then I encounter a problem where I want to set a default filter that set the results based on a specific template. A use case would be if I want to create a search result page for a News section where I want to build search result page that by default listed the results only based on News template.

Coveo free edition has no support for content editor to change the filter using the Sitecore rules, but for learning purposes you can do the following to enable it to know more about how Coveo build it’s queries.

First off let’s duplicate Coveo Search Parameter item in /sitecore/templates/CoveoModule/Search/Coveo Search Parameters. Create a new field called CustomFilterExpressionRules and set the type to Rules with the source field set to “rulespath=/sitecore/system/Settings/Rules/Coveo Search Rules&hideactions=true&includecommon=false”

duplicate-coveo-searchparameters

The duplicate Coveo Search Model, you can find this item in /sitecore/layout/Models/Coveo/Search Model

duplicate-coveo-searchmodel

Here I give it a name as Search Model Custom and set the Model Type to “MyApp.SearchModel, MyApp”

class MyApp.SearchModel

public class SearchModel : Coveo.UI.Mvc.Models.SearchModel, ISearchModel
{
 private IEnumerable<CoveoRule> _customFilterRules;

 public IEnumerable<CoveoRule> CustomFilterRules
 {
 get { return _customFilterRules ?? (_customFilterRules = GetRulesField("CustomFilterExpressionRules")); }
 }

 public new string HiddenExpression
 {
 get
 {
 var searchContext =
 SitecoreHelper.GetSearchIndex(BoundRendering.Item.ToIndexable())
 .CreateSearchContext(SearchSecurityOptions.EnableSecurityCheck);
 var str = "";
 if (CustomFilterRules.Any())
 {
 str = RulesHelper.GetQueryExpression(CustomFilterRules, searchContext);
 if (!string.IsNullOrEmpty(str))
 str = " " + str;
 }
 return str + GetExcludedTemplatesExpression();
 }
 }

 public override ErrorReport ValidateModel()
 {
 var errorReport = base.ValidateModel();
 ValidateRules(errorReport, CustomFilterRules, ValidateRule);
 return errorReport;
 }

 private void ValidateRule(ErrorReport errorReport, CoveoRule rule)
 {
 if (rule.Condition != null)
 rule.Condition.ValidateCondition(errorReport);
 else
 errorReport.AddError(Labels["The rule must have a condition."]);
 }

 private void ValidateRules(ErrorReport p_Report, IEnumerable<CoveoRule> p_Rules,
 Action<ErrorReport, CoveoRule> p_ValidationMethod)
 {
 foreach (var coveoRule in p_Rules)
 {
 var p_SubReport = new ErrorReport();
 p_ValidationMethod(p_SubReport, coveoRule);
 p_Report.AppendAsGroup(coveoRule.Name, p_SubReport);
 }
 }

 private IEnumerable<CoveoRule> GetRulesField(string fieldName)
 {
 var list = new List<CoveoRule>();
 var stringParam = ParametersHelper.GetStringParam(fieldName);
 if (!string.IsNullOrEmpty(stringParam))
 list.AddRange(RulesHelper.ParseRules(SitecoreContext.GetCurrentDatabase(), stringParam));

 return list;
 }

 private string GetExcludedTemplatesExpression()
 {
 var list = new List();
 if (!IncludeBucketFoldersInResults)
 list.Add(new Guid("{ADB6CA4F-03EF-4F47-B9AC-9CE2BA53FF97}").ToString("D"));
 if (!IncludeMediaFoldersInResults)
 list.Add(new Guid("{FE5DD826-48C6-436D-B87A-7C4210C7413B}").ToString("D"));
 var str = "";
 if (list.Any())
 str = " " + 
 string.Format("NOT {0}==(\"{1}\")", ToCoveoFieldName("templateid"),
 string.Join("\",\"", list.ToArray()));
 return str;
 }
}

We have the custom rendering parameter and custom search model now we need to create a new search view rendering that uses this custom parameter and model. Go to /sitecore/layout/Renderings/Coveo/Coveo Search View . Duplicate the item and name it Coveo Search View Custom. Set the model field to our custom model item and the rendering parameter to our custom parameter item.

duplicate-coveo-searchview

Now to test it, I created a new page using the Coveo Search (MVC) insert option and then change the Search View rendering with the Search View Custom that I made.

set-customcoveoview-rendering

Edit the properties, it shows up a dialog window where we can update the filter based on the custom field that we previously created.

The result

coveo-searchresult

The key here is the HiddenExpression property, it returns the filter expression that Coveo understand based on the Rules value that we’ve set. In the above result it output the following value to filter the result” (@falltemplates99785=\”f1828a2c7e5d4bbd98ca320474871548\”) NOT @ftemplateid99785==(\”adb6ca4f-03ef-4f47-b9ac-9ce2ba53ff97\”,\”fe5dd826-48c6-436d-b87a-7c4210c7413b\”)”