【问题标题】:How I can use predicate buider for Sitecore Lucene Search我如何将谓词构建器用于 Sitecore Lucene 搜索
【发布时间】:2016-09-22 09:39:06
【问题描述】:

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

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

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

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

我按照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);

上面给出的代码对我不起作用。我知道我做错了什么,因为我不擅长谓词生成器,条件在复选框组之间不起作用。

谁能告诉我在给定的代码中我哪里错了,或者有什么最好的方法来实现这一点。

任何帮助将不胜感激

【问题讨论】:

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


    【解决方案1】:

    我最近做了类似的事情,它的工作原理是这样的:

    创建你的“或”谓词:

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

    【讨论】:

    • 感谢@Gatogordo 让我试试这个
    • 嘿,感谢您的投入,我确实使用了您的一些方法并使用了我的旧代码!再次感谢:)
    【解决方案2】:

    您需要有一个主要谓词来加入带有 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);
    

    希望这会对你有所帮助。

    【讨论】:

    • 感谢@Vikram,我对旧代码做了一些小改动,比如将新构建器放入 if 语句中,它对我有用,但为您的快速帮助投了赞成票\p :)
    【解决方案3】:

    感谢大家提供您的意见 -

    我根据您的输入更新了代码,现在它可以工作了。 我的旧代码有两个更改,一个是 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);
    }
    

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

    再次感谢大家的帮助!!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多