Sitecore Lucene Search filtering with Predicate Builder

Posted 09/24/2016 by Yogeshwer Sharma

Recently I was working on a project where I got a requirement for filtering search results on the bases of multiple filters.

I realized this was a perfect place to use a predicate builder. I had used predicate builders previously, but that was only used for simple filtering like keywords and template based results.

First let me give you an overview about the requirement.

We have a multiple groups of Checkbox listing, in each group user can select multiple values and the condition between those values should be OR and between groups condition should be AND.  

To implement this I started looking on internet I found many posts regarding same, finally I found a very good post which explain predicate builder in such a great way.

I read this post and refreshed my memory about predicate builders. Suitably refreshed, I started building.

For every checkbox group we have a multilist field on our content pages where we are searching these filters.

Below is the API which I wrote to handle these filters -

var builder = PredicateBuilder.True();
//Filter with TemplateId
builder = builder.And(i => i.TemplateId == [TemplateId]);

//Created new builder for Category items and added again into main builder
if (!string.IsNullOrEmpty(Categorys))
{   var Categorybuilder = PredicateBuilder.False();
    var CategoryItems = Categorys.Split('|');
    foreach (var Category in CategoryItems)
        var ct = Sitecore.ContentSearch.Utilities.IdHelper.NormalizeGuid(Categorys, true);
        Categorybuilder = Categorybuilder.Or(i => i.Category.Contains(ct));
    builder = builder.And(Categorybuilder);

//Created new builder for Service items and added again into main builder
if (!string.IsNullOrEmpty(Service))
    var Servicebuilder = PredicateBuilder.False();
    var ServiceItems = Service.Split('|');
    foreach (var ser in ServiceItems)
        var si = Sitecore.ContentSearch.Utilities.IdHelper.NormalizeGuid(ser, true);
        Servicebuilder = Servicebuilder.Or(i => i.Service.Contains(si));
   builder = builder.And(Servicebuilder);

//Created new builder for product items and added again into main builder
if (!string.IsNullOrEmpty(products))
    var productsbuilder = PredicateBuilder.False();
    var productItems = products.Split('|');
    foreach (var product in productItems)
        var pd = Sitecore.ContentSearch.Utilities.IdHelper.NormalizeGuid(product, true);
        productsbuilder = productsbuilder.Or(i => i.Category.Contains(pd));
    builder = builder.And(productsbuilder);

//Filter for keyword
if (!string.IsNullOrEmpty(keyword))
    builder = builder.And(i => i.Content.Contains(keyword));
var results=context.GetQueryable().Where(builder).Select(i => (Item)i.GetItem()).ToList()

Here TestResultItem is a class to index custom fields (Products, category and services). 

public class TestResultItem : SearchResultItem
	    //Category multilist field on detail page
        public string Category { get; set; }

		//Service multilist field on detail page
        public string Service { get; set; }
		//Product multilist field on detail page
        public string Product { get; set; }

I know there are many more ways to implement same and may be best ways to implement this but I found this very easy to implement and easy to understand.

I hope this will help you to understand implementation of search filtering in Sitecore.


Add your comment