Как получить все PageTemplate, который содержит определенный компонент?

У меня есть шаблон страницы ArticlePageTemplate, это ArticlePageTemplate содержит компонент под названием Articles, Article компонент имеет поле данных под названием Header, SubHeader, Date, а также Content,

Детали презентации ArticlesPageTemplate

Детали презентации страницы

Использование Lucene в sitecore 8. Как получить весь ArticlePageTemplate, содержащий компонент Article со значением "News" в подзаголовке компонента Article.

Структура сайта:

Sitecore tree

Вот мой код

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 используя код выше, но я не могу отфильтровать его, чтобы получить только те, ArticlePageTemplate который содержит Article компонент, в котором Article подзаголовок компонента - "новости".

Я не знаю, как получить компонент статей ArticlePageTemplate чтобы я мог добавить их к своему поисковому запросу в Lucene.

Любой совет приветствуется.

Замечания:

Источник данных ArticlesComponent может измениться, так что это не всегда ребенок ArticlesPageTemplate,

ОБНОВЛЕНИЕ (11.09.2015)

Я попробовал то, что предложил Ричард, но это не работает.

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

2 ответа

Решение

Я вижу два подхода, которые вы можете использовать здесь:

  • Создайте "вычисляемое поле" для поля подзаголовка компонента Article. Вы должны настроить это так, чтобы индекс был настроен для поиска этого компонента в элементе с шаблоном ArticlePageTemplate и вычисления значения подзаголовка в индексе. По сути, это заставляет индекс думать, что поле подзаголовка на самом деле является полем элемента ArticlePageTemplate. Затем вы можете сделать обычный поиск по индексу.

  • Найдите справочные страницы для компонента. В этом сценарии вы выполняете поиск компонентов в индексе (не ArticlePageTemplate), и если вы можете зависеть от структуры вашей папки и не можете повторно использовать ее на разных страницах, вы можете просто получить родительскую страницу любого результата поиска. (item.Parent.Parent, в вашем примере структуры)

ОБНОВЛЕНИЕ: Некоторые ссылки для вычисляемых полей:

Вам нужно будет создать собственный класс, который позволит вам фильтровать по вашему полю, вы можете основывать его на 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....
    }
}
Другие вопросы по тегам