我如何为 Sitecore Lucene 搜索使用谓词构建器

How I can use predicate buider for Sitecore Lucene Search

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

  1. 产品
  2. 类别
  3. 服务

现在在列表页面上,我将所有三个组过滤器都作为复选框,如下图所示 -

我的要求是我想在组内应用 Or 就像产品之间的条件应该是 Or 并且两组之间的条件应该是。例如产品和类别应该是 And.

我关注 http://getfishtank.ca/blog/building-dynamic-content-search-linq-queries-in-sitecore-7 博客 post 来实现这个

为了实现这个我正在努力 -

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 构建器,Or 条件在复选框组之间不起作用。

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

任何帮助将不胜感激

我最近做了类似的事情,效果是这样的:

创建您的 "or" 谓词:

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

您需要有一个主谓词来使用 AND 条件连接过滤器,而其他谓词(例如类别或服务或产品)则需要使用 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);

希望对您有所帮助。

感谢大家提供意见 -

我根据您的输入更新了代码,现在它可以正常工作了。 我的旧代码有两个变化,一个是 multilist 的构建器应该在 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);
}

在上面的代码中,Category、Service 和 products 是管道分隔的值,它们来自 Sitecore Multi-list 字段。

再次感谢大家的帮助!!