我在编写查询以选择项目后代具有某些属性的项目时遇到了一些麻烦。我正在使用Sitecore 7
我想选择带有平面图标的项目,其中任何绿色检查项目的属性X的值为Y.
我是否需要做一些特别的事情来指导孩子? 我的查询尝试是:
var master = Sitecore.ContentSearch.ContentSearchManager.GetIndex("sitecore_master_index");
using (var context = master.CreateSearchContext())
{
var results = context.GetQueryable<SearchResultItem>()
.Where(x => x.TemplateId == productTemplateId
&& x.GetDescendants<SearchResultItem>(context).Any(y => y["X"] == "Y"))
.GetResults();
var hits = results.Hits.ToArray();
}
这会引发以下异常:
System.NotSupportedException: The method 'GetDescendants' is not supported. Declaring type: Sitecore.ContentSearch.SearchTypes.SearchResultItem
Result StackTrace:
at Sitecore.ContentSearch.Linq.Parsing.ExpressionParser.VisitItemMethod(MethodCallExpression methodCall)
at Sitecore.ContentSearch.Linq.Parsing.ExpressionParser.VisitMethodCall(MethodCallExpression methodCall)
at Sitecore.ContentSearch.Linq.Parsing.ExpressionParser.Visit(Expression expression)
at Sitecore.ContentSearch.Linq.Parsing.ExpressionParser.VisitAnyMethod(MethodCallExpression methodCall)
at Sitecore.ContentSearch.Linq.Parsing.ExpressionParser.VisitQueryableMethod(MethodCallExpression methodCall)
at Sitecore.ContentSearch.Linq.Parsing.ExpressionParser.VisitMethodCall(MethodCallExpression methodCall)
at Sitecore.ContentSearch.Linq.Parsing.ExpressionParser.Visit(Expression expression)
at Sitecore.ContentSearch.Linq.Parsing.ExpressionParser.VisitBinary(BinaryExpression expression)
at Sitecore.ContentSearch.Linq.Parsing.ExpressionParser.Visit(Expression expression)
at Sitecore.ContentSearch.Linq.Parsing.ExpressionParser.VisitWhereMethod(MethodCallExpression methodCall)
at Sitecore.ContentSearch.Linq.Parsing.ExpressionParser.VisitQueryableMethod(MethodCallExpression methodCall)
at Sitecore.ContentSearch.Linq.Parsing.ExpressionParser.VisitMethodCall(MethodCallExpression methodCall)
at Sitecore.ContentSearch.Linq.Parsing.ExpressionParser.Visit(Expression expression)
at Sitecore.ContentSearch.Linq.Parsing.ExpressionParser.VisitGetResultsMethod(MethodCallExpression methodCall)
at Sitecore.ContentSearch.Linq.Parsing.ExpressionParser.VisitQueryableExtensionMethod(MethodCallExpression methodCall)
at Sitecore.ContentSearch.Linq.Parsing.ExpressionParser.VisitMethodCall(MethodCallExpression methodCall)
at Sitecore.ContentSearch.Linq.Parsing.ExpressionParser.Visit(Expression expression)
at Sitecore.ContentSearch.Linq.Parsing.ExpressionParser.Parse(Expression expression)
at Sitecore.ContentSearch.Linq.Parsing.GenericQueryable`2.GetQuery(Expression expression)
at Sitecore.ContentSearch.Linq.Parsing.GenericQueryable`2.Execute[TResult](Expression expression)
at Sitecore.ContentSearch.Linq.QueryableExtensions.GetResults[TSource](IQueryable`1 source)
我不确定为什么。
答案 0 :(得分:1)
您无法使用GetDescendants
,因为它尚未在ContentSearch表达式解析器中实现。
在Sitecore搜索中,您需要按项目路径查找后代
因此,首先获取与模板 productTemplateId 匹配的项目,然后获取项目路径以第一个结果的路径开头的项目。
我确定有一种方法可以在一个表达式中执行此操作(可能使用Join),但我不知道如何。
答案 1 :(得分:0)
您还可以创建自定义计算字段,存储已检查项目的值并在自定义字段上查询。
编辑:使用这种方法,当您保存一个已检查的项目时,您还必须触发parent.parent项目的索引更新(您可以使用事件并调用IndexCustodian.UpdateItem来执行此操作)。
答案 2 :(得分:0)
Sitecore内容搜索API不支持使用&#39; GetDescendants&#39;方法,但您可以使用以下代码作为解决方法,
请注意我对您的Green检查模板进行过滤,而不是对productTemplateId进行过滤:
var master = Sitecore.ContentSearch.ContentSearchManager.GetIndex("sitecore_master_index");
using (var context = master.CreateSearchContext())
{
var Products = new List<Item>();
var results = context.GetQueryable<SearchResultItem>()
.Where(x => x.TemplateId == GreenCheckTemplateID
&& x["X"] == "Y")
.GetResults();
foreach (SearchHit<SitecoreItem> result in results.Hits)
{
var product = result.Document.GetItem().Parent.Parent;
if(!Products.Where(i=>i.ID.Equals(product.ID).Any())
{
Products.Add(product);
}
}
}
答案 3 :(得分:0)
之前的答案是正确的,因为Linq to ContentSearch不包含GetDescendants()的定义。
克服此限制的另一个选择是创建自己的IQueriable扩展,类似于此处描述的内容:http://thegrumpycoder.com/post/75297631359/extending-sitecore-contentsearch-with-iqueryable。您可以创建FilterDescendants(fieldName,value)扩展,它接受字段名称和值以过滤后代。
所以你的陈述将是
var results = context.GetQueryable<SearchResultItem>()
.Where(x => x.TemplateId == productTemplateId)
.FilterDescendants(fieldName, value)
.GetResults();
很干净!