У меня есть набор товарных позиций. У каждой позиции продукта есть многострочное поле, которое указывает на набор позиций типа продукта. Когда я нахожусь на странице продукта, я хочу показывать постраничный список связанных элементов. Это должны быть элементы, которые имеют общий тип продукта с текущим выбранным элементом. У меня проблемы, потому что товары могут быть разных типов. Мне нужно разделить список типов на текущий элемент и сравнить его со списком продуктов в выражении. По какой-то причине split и contains выбрасывают исключения времени выполнения, и я не могу понять, почему. Я видел кое-что о построителе предикатов, используемом для динамических запросов, и я попытаюсь использовать его с тем, что у меня есть в настоящее время, но я хотел бы знать, почему это нельзя сделать прямо в предложении where.

Еще одна проблема, с которой я столкнулся, заключается в том, что список идентификаторов, хранящихся в solr, лишается их символов '{', '}' и '-'.

2
Teeknow 29 Ноя 2014 в 02:05
Пожалуйста, опубликуйте свой код и ошибку, которую вы получаете
 – 
Ahmed Okour
29 Ноя 2014 в 13:33

2 ответа

Лучший ответ

Если вы уже находитесь на странице продукта, я предполагаю, что у вас уже есть элемент продукта, и этот элемент продукта должен иметь многострочное поле «ProductType». Вы можете использовать Sitecore.Data.Fields.MultilistFiled, чтобы не беспокоиться о разделении необработанных значений.

Затем вы можете использовать конструктор предикатов Sitecore для построения предиката поиска, который, как я предполагаю, вы хотите найти все продукты, имеющие один похожий тип продукта. Вы должны настроить эту логику поиска по мере необходимости. Я использую ObjectIndexerKey (подробнее см. Здесь -> http://www.sitecore.net/Learn/Blogs/Technical-Blogs/Sitecore-7-Development-Team/Posts/2013/05/Sitecore-7- Predicate-Builder.aspx), чтобы перейти к именованному полю, но вы должны построить правильную модель поиска и фактически определить ProductTypes как List или что-то подобное. Вам может потребоваться добавить другие условия к предикату поиска, такие как path или templateid, чтобы ограничить ваши результаты. После этого вы можете просто выполнить поиск и использовать результаты.

Поскольку Solr удаляет специальные символы, это ожидаемое поведение, основанное на анализаторе, используемом в поле. 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
     }
}
2
Matt Gartman 29 Ноя 2014 в 03:40
Да, это имеет большой смысл. Разбейте его на несколько шагов, чтобы нам не нужно было использовать .Split. В итоге это было изменено на использование context.GetQueryable.AsEnumerable().Where(mySplitFiltering). Это действительно сбивает с толку, что приведение к Enumerable делает так, что Where волшебным образом поддерживает String.Split. До сих пор то, что я видел, говорит, что AsEnumerable ничего не меняет, но для меня это означает, что функция разделения по-прежнему не должна поддерживаться (или она выполняется вне запроса sql).
 – 
Teeknow
3 Дек 2014 в 23:39
1
Привет, @Matt, ты используешь особую реализацию для SearchResultItemModel здесь? Также я продолжаю получать сообщение об ошибке (ID)x[ObjectIdex.... о том, что идентификатор не содержит определения для «Содержит». Можете ли вы помочь, пожалуйста?
 – 
Jay
11 Ноя 2016 в 15:03

Просто улучшение кода @Matt Gartman. Ошибка (идентификатор не содержит определения для Contains), которая продолжает появляться, потому что .Contains не является функцией идентификатора типа, я рекомендую вам преобразовать ее в строковый тип, как показано ниже

foreach (ID id in multilistField.TargetIDs)
 {
      pred = pred.Or(x => (Convert.ToString((ID)x[(ObjectIndexerKey)"ProductType"]).Contains(id.toString())));
 }
0
GSKKC 5 Ноя 2019 в 08:37