3

当我有一组 Sitecore ID(例如 MultilistField 中的 TargetID)时,如何查询 ContentSearchManager 以返回所有 SearchResultItem 对象?

我尝试了以下给出“仅支持常量参数”的方法。错误。

using (var s = Sitecore.ContentSearch.ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
{
    rpt.DataSource = s.GetQueryable<SearchResultItem>().Where(x => f.TargetIDs.Contains(x.ItemId));
    rpt.DataBind();
}

我想我可以使用多个 OR 查询手动构建 Linq 查询。有没有一种方法可以用来Sitecore.ContentSearch.Utilities.LinqHelper为我构建查询?

假设我让这项技术发挥作用,是否值得仅将其用于 10 个项目?我刚刚开始我的第一个 Sitecore 7 项目,我想尽可能多地使用索引。

最后,页面编辑器是否支持以 SearchResultItem 作为源的编辑字段?

更新 1 我编写了这个函数,它使用了 dunston 建议的谓词构建器。我还不知道这是否真的值得使用(而不是项目)。

public static List<T> GetSearchResultItemsByIDs<T>(ID[] ids, bool mustHaveUrl = true)
    where T : Sitecore.ContentSearch.SearchTypes.SearchResultItem, new()
{
    Assert.IsNotNull(ids, "ids");
    if (!ids.Any())
    {
        return new List<T>();
    }

    using (var s = Sitecore.ContentSearch.ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
    {
        var predicate = PredicateBuilder.True<T>();
        predicate = ids.Aggregate(predicate, (current, id) => current.Or(p => p.ItemId == id));

        var results = s.GetQueryable<T>().Where(predicate).ToDictionary(x => x.ItemId);
        var query = from id in ids
                  let item = results.ContainsKey(id) ? results[id] : null
                  where item != null && (!mustHaveUrl || item.Url != null)
                  select item;

        return query.ToList();
    }
}

它强制结果与 IDs 数组中提供的顺序相同,这在我的情况下很重要。(如果有人知道这样做的更好方法,很想知道)。

默认情况下,它还确保 Item 具有 URL。

然后我的主要代码变为:

var f = (Sitecore.Data.Fields.MultilistField) rootItem.Fields["Main navigation links"];
rpt.DataSource = ContentSearchHelper.GetSearchResultItemsByIDs<SearchResultItem>(f.TargetIDs);
rpt.DataBind();

我仍然很好奇页面编辑器通常如何处理 SearchResultItem 或 POCO(我的第二个问题),现在我将继续研究。

感谢阅读,史蒂夫

4

1 回答 1

3

您需要使用谓词构建器来创建多个 OR 查询或 AND 查询。

下面的代码应该可以工作。

        using (var s = Sitecore.ContentSearch.ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
        {
            var predicate = PredicateBuilder.True<SearchResultItem>();

            foreach (var targetId in f.Targetids)
            {
                var tempTargetId = targetId;
                predicate = predicate.Or(x => x.ItemId == tempTargetId)
            }
            rpt.DataSource = s.GetQueryable<SearchResultItem>().Where(predicate);
            rpt.DataBind();
        }
于 2013-09-18T10:48:01.727 回答