我如何使用谓词buider进行Sitecore Lucene Search

时间:2016-09-22 09:39:07

标签: sitecore lucene.net sitecore8 predicatebuilder sitecore-lucene

我正在使用Sitecore 8.1,我正在通过Sitecore lucene为其中一个页面实现过滤功能。 Fot过滤我正在使用谓词构建器。我有详细项目的3个多列表字段

  1. 产品
  2. 分类
  3. 服务
  4. 现在在列表页面上,我将所有三个组过滤器作为复选框,如下图所示 - enter image description here

    我的要求是我想在组内部应用之间的产品条件应该是,两组之间的条件应该是。例如,产品和类别应为

    我按照http://getfishtank.ca/blog/building-dynamic-content-search-linq-queries-in-sitecore-7博文发布了这个

    要实现这一点,我正在尝试 -

    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);
    

    以上给出的代码对我不起作用。我知道我做错了,因为我对Predicate构建器不好,条件在复选框组之间不起作用。

    任何人都可以告诉我在给定代码中出错的地方或任何实现此目的的最佳方法。

    任何帮助将不胜感激

3 个答案:

答案 0 :(得分:2)

我最近做了类似的事情,它的工作原理如下:

创建“或”谓词:

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

其中tagValues是包含规范化guid的IEnumerable。

我为几个guid列表执行此操作。最后我将它们包装在一起:

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

查看您的代码:首先改变

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

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

答案 1 :(得分:1)

你需要有一个主谓词来加入AND条件&amp;的过滤器。其他谓词(例如,类别或服务或产品)在内部使用OR条件加入过滤器。

// This is your main predicate builder 
var builder = PredicateBuilder.True<TestResultItem>();
var Categorybuilder = PredicateBuilder.False<TestResultItem>();
var Servicebuilder = PredicateBuilder.False<TestResultItem>();
var productsbuilder = PredicateBuilder.False<TestResultItem>();
builder = builder.And(Categorybuilder);
builder = builder.And(Servicebuilder);
builder = builder.And(productsbuilder);

希望这会对你有所帮助。

答案 2 :(得分:0)

感谢所有人提供您的意见 -

我根据您的输入更新了代码,现在它正在运行。 我的旧代码中有两处更改,一种是多列表的构建器应该在if语句中,并且还将新创建的构建器添加到同一位置的主构建器(在if语句中) -

我正在分享下面的代码,以便如果有人想要使用它,他可以轻松地从这里复制 -

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


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


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

在上面的代码中,分类,服务和产品是来自Sitecore多列表字段的管道分隔值。

再次感谢大家的帮助!!