Sitecore Solr按多列表搜索另一个多列表中的值

时间:2014-11-28 23:05:40

标签: solr sitecore sitecore7

我有一套产品。每个产品项都有一个多列表字段,指向一组产品类型项。在产品页面上,我想显示相关项目的分页列表。这些应该是与当前所选项目共享产品类型的项目。我遇到了一些麻烦,因为产品可能有多种类型。我需要在当前项目上拆分类型列表,并根据表达式中的产品列表进行检查。由于某种原因,split和contains会抛出运行时异常,我无法弄清楚原因。我看到有关谓词构建器用于动态查询的一些内容,我将尝试将其与我目前的内容一起使用,但我想知道为什么不能直接在where子句中完成。< / p>

我遇到的另一个问题是,存储在solr中的ID列表被剥夺了他们的&#39; {&#39;}&#39;}&#39;和&#39; - &# 39;字符。

2 个答案:

答案 0 :(得分:2)

如果您已经在产品页面上,我假设您已经拥有产品项目,并且该产品项目应该具有&#34; ProductType&#34;多列表字段。您可以使用Sitecore.Data.Fields.MultilistFiled来避免担心必须拆分原始值。

然后,您可以使用Sitecore的Predicate Builder构建您的搜索谓词,我假设您要查找具有相似产品类型的所有产品。您应该根据需要调整此搜索逻辑。我使用ObjectIndexerKey(请参阅此处 - &gt; http://www.sitecore.net/Learn/Blogs/Technical-Blogs/Sitecore-7-Development-Team/Posts/2013/05/Sitecore-7-Predicate-Builder.aspx)来查找命名字段,但是您应该构建一个正确的搜索模型,并将ProductTypes实际定义为List&lt; ID&GT;或类似的东西。您可能还需要向搜索谓词添加其他条件,例如path或templateid以限制结果。之后,您可以执行搜索并使用结果。

就Solr剥离特殊字符而言,这是基于字段上使用的Analyzer的预期行为。 Sitecore和Solr将应用适当的查询时间分析器来匹配,因此只要使用正确的类型,您就不必担心格式化。

var pred = PredicateBuilder.True<SearchResultItem>();

Sitecore.Data.Fields.MultilistField multilistField = Sitecore.Context.Item.Fields["ProductTypes"];
if (multilistField != null)
{
     foreach (ID id in multilistField.TargetIDs)
     {
          pred = pred.Or(x => ((ID)x[(ObjectIndexerKey)"ProductType"]).Contains(id);
     }
}


ISearchIndex _searchIndex = ContentSearchManager.GetIndex("sitecore_master_index");  // change to proper search index

using (var context = _searchIndex.CreateSearchContext())
{
     var relatedProducts = context.GetQueryable<SearchResultItemModel>().Where(pred);

     foreach(var relatedProduct in relatedProducts)
     {
          // do something here with search results
     }
}

答案 1 :(得分:0)

只是对@Matt Gartman代码的改进, 一直弹出的错误(ID不包含Contains的定义)是因为.Contains不是Type ID的功能,我建议您按以下字符串类型进行转换

foreach (ID id in multilistField.TargetIDs)
 {
      pred = pred.Or(x => (Convert.ToString((ID)x[(ObjectIndexerKey)"ProductType"]).Contains(id.toString())));
 }