如何通过ContentSearchManager查询多个ID?

时间:2013-09-18 08:34:15

标签: sitecore sitecore7

当我有一个Sitecore ID数组时,例如MultilistField中的TargetIDs,如何查询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();
    }
}

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

默认情况下,它还可确保项目具有URL。

我的主要代码变为:

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

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

感谢阅读, 史蒂夫

1 个答案:

答案 0 :(得分: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();
        }