【问题标题】:How to get all PageTemplate that contains a specific component?如何获取包含特定组件的所有 PageTemplate?
【发布时间】:2015-09-10 09:53:34
【问题描述】:

我有一个名为ArticlePageTemplate 的页面模板。这个ArticlePageTemplate 包含一个名为Articles 的组件。 Article 组件具有名为 HeaderSubHeaderDateContent 的数据字段。

ArticlesPageTemplate的介绍详情

在sitecore 8中使用Lucene。如何获取所有ArticlePageTemplate,其中包含Article组件子标题中值为“News”的Article组件。

网站核心结构:

这是我的代码

public class LuceneSearchService : ILuceneSearchService, IDisposable
{
    bool disposed = false;
    // Instantiate a SafeHandle instance.
    SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true);

    private IProviderSearchContext _SearchContext;
    private ISearchIndex _Index;

    private string _IndexName = "sitecore_web_index";

    public string IndexName
    {
        get { return _IndexName; }
        set { _IndexName = value; }
    }


    public LuceneSearchService()
    {
        _Index = ContentSearchManager.GetIndex(this.IndexName);
        _SearchContext = _Index.CreateSearchContext();
    }

    public IQueryable<SearchResultItem> PerformSearch(string searchPath)
    {

        var searchQuery = _SearchContext.GetQueryable<SearchResultItem>()
        .Where(i => i.Path.StartsWith(searchPath));

        return searchQuery;

    }

    public IQueryable<SearchResultItem> PerformSearch(string searchPath, string templateName)
    {
        var searchQuery = PerformSearch(searchPath).Where(x => x.TemplateName == templateName);

        return searchQuery;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);            
    }

    // Protected implementation of Dispose pattern. 
    protected virtual void Dispose(bool disposing)
    {
        if (disposed)
            return;

        if (disposing)
        {
            handle.Dispose();
            _SearchContext.Dispose();
            _Index.Dispose();
        }

        // Free any unmanaged objects here. 
        //
        disposed = true;
    }
}

代码实现

public void SearchArticles()
    {
        var articles = SearchService.PerformSearch("/sitecore/content", "ArticlePageTemplate").ToList();
        foreach (var article in articles){
            var articleName = article;
        }


    }

我可以使用上面的代码获取所有ArticlesPageTemplate,但我无法过滤它以仅获取那些包含Article 组件的ArticlePageTemplate,其中Article 组件的子标题是“新闻”。

我不知道如何获取 ArticlePageTemplate 的文章组件,因此我可以将它们添加到我在 lucene 中的搜索查询中。

感谢任何建议。

注意:

ArticlesComponent 的数据源可能会发生变化,因此它并不总是ArticlesPageTemplate 的子级。

更新(2015 年 9 月 11 日)

我尝试了 Richard 的建议,但没有奏效。

var articles = SearchService
        .PerformSearch<ArticleResultItem>("/sitecore/content", "ArticlePageTemplate")
        .Where(item => item.SubHeader == "News").ToList();

使用上面的查询不会产生任何结果,但使用下面的查询会返回一个结果,但它检索的是 ArticleComponent 而不是 ArticlePageTemplate。

var articles = SearchService
        .PerformSearch<ArticleResultItem>("/sitecore/content"
        .Where(item => item.SubHeader == "News").ToList();

解决方案:

计算字段有效。从以下链接查看 VisualizationField.cs:

https://gist.github.com/techphoria414/7604814

【问题讨论】:

    标签: c# sitecore lucene.net sitecore8 sitecore-lucene


    【解决方案1】:

    我可以在这里看到两种方法:

    • 为 Article 组件子标题字段构建一个“计算字段”。您将进行设置,以便将索引配置为使用 ArticlePageTemplate 模板在项目上查找此组件,并且将子标题值计算到索引中。这实质上使索引认为 subheader 字段实际上是 ArticlePageTemplate 项上的字段。然后就可以对索引进行常规搜索了。

    • 查找组件的参考页面。 在这种情况下,您搜索组件的索引(而不是 ArticlePageTemplate),如果您可以依赖您的文件夹结构并且您不跨页面重复使用,然后您可以抓取任何搜索结果的父页面。 (item.Parent.Parent,在您的示例结构中)

    更新:计算字段的一些链接:

    【讨论】:

    • 嗨 Jay,我也试过 item.Parent.Parent 但 item.Parent 没有名为 Parent 的属性。
    • 嗨@Pinoy2015,对于第一种方法,计算字段是您在索引中编写和配置的代码片段,因此项目可以获得通常无法获得的数据。我会找到一个链接并添加到我的原始答案中。不过,我不确定您的 item.Parent 问题。 Parent 属性应该返回一个 Item,这意味着它也应该有一个 Parent 属性。
    【解决方案2】:

    您需要创建一个自定义类,允许您根据自己的字段进行过滤,您可以将其基于 SearchResultItem 类。

    比如:

    public class ArticleResultItem : SearchResultItem
    {
        [IndexField("SubHeader")]
        public string SubHeader { get;set; }
    }
    

    然后,如果您将 PerformSearch 方法更改为采用基于 SearchResultItem 的泛型,您可以在调用方法中使用该字段进行过滤。

    public IQueryable<T> PerformSearch<T>(string searchPath)
        where T: SearchResultItem
    {
    
        var searchQuery = _SearchContext.GetQueryable<T>()
        .Where(i => i.Path.StartsWith(searchPath));
    
        return searchQuery;
    
    }
    
    public IQueryable<T> PerformSearch<T>(string searchPath, string templateName)
        where T: SearchResultItem
    {
        var searchQuery = PerformSearch<T>(searchPath).Where(x => x.TemplateName == templateName);
    
        return searchQuery;
    }
    

    然后你会这样称呼它:

    public void SearchArticles()
    {
        var articles = SearchService
            .PerformSearch<ArticleResultItem>("/sitecore/content", "ArticlePageTemplate")
            .Where(item => item.SubHeader == "News").ToList();
        foreach (var article in articles){
            var articleName = article;
            // Do something with the list here....
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-25
      • 1970-01-01
      相关资源
      最近更新 更多