Search code examples
sitecorelucene.netsitecore8predicatebuildersitecore-lucene

How I can use predicate buider for Sitecore Lucene Search


I am working on Sitecore 8.1 and I am implementing filter functionality for one of the page by Sitecore lucene. Fot filtering I am using predicate builder. I have 3 multi-lists field on detail items

  1. Product
  2. Category
  3. Services

Now on listing page I have all three group filters as checkboxes as given in below image - enter image description here

My Requirement is I want to apply Or between inside the group like between products condition should be Or and between two groups condition should be And. For example products and Category should be And.

I followed http://getfishtank.ca/blog/building-dynamic-content-search-linq-queries-in-sitecore-7 blog post to implement this

To achieve this what I am trying -

var builder = PredicateBuilder.True<TestResultItem>();
var Categorybuilder = PredicateBuilder.False<TestResultItem>();
if (!string.IsNullOrEmpty(Categorys))
{
    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));
    }
}

var Servicebuilder = PredicateBuilder.False<TestResultItem>();
if (!string.IsNullOrEmpty(Service))
{
    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));
    }
}

var productsbuilder = PredicateBuilder.False<TestResultItem>();
if (!string.IsNullOrEmpty(products))
{
    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));
    }
}

Servicebuilder = Servicebuilder.Or(Categorybuilder);
productsbuilder = productsbuilder.Or(Servicebuilder);
builder = builder.And(productsbuilder);

The above given code is not working for me. I know I am doing something wrong as I am not good with Predicate builder, Or condition is not working between check boxes group.

Can anyone please tell me where I am wrong in given code or any best way to achieve this.

Any help would be appreciated


Solution

  • I did something similar recently and it works like this:

    Create your "or" predicates:

    var tagPredicate = PredicateBuilder.False<BlogItem>();
    tagPredicate = tagValues.Aggregate(tagPredicate, (current, tag) => current.Or(p => p.Tags.Contains(tag)))
    

    where tagValues is an IEnumerable containing the normalized guids.

    I do this for several guid lists. In the end I wrap them together like this:

    var predicate = PredicateBuilder.True<BlogItem>();
    predicate = predicate.And(tagPredicate);
    predicate = predicate.And(...);
    

    Looking at your code: first of all change

    Servicebuilder = Servicebuilder.Or(Categorybuilder);
    productsbuilder = productsbuilder.Or(Servicebuilder);
    builder = builder.And(productsbuilder);
    

    into

    builder = builder.And(Categorybuilder);
    builder = builder.And(Servicebuilder);
    builder = builder.And(productsbuilder);