如何获取包含特定组件的所有 PageTemplate?
How to get all PageTemplate that contains a specific component?
我有一个名为 ArticlePageTemplate
的页面模板。此 ArticlePageTemplate
包含一个名为 Articles
的组件。 Article
组件具有名为 Header
、SubHeader
、Date
和 Content
的数据字段。
ArticlesPageTemplate
的演示文稿详情
在 sitecore 8 中使用 Lucene。如何获取所有包含 Article 组件的 ArticlePageTemplate,其中 Article 组件的子标题中的值为 "News"。
站点核心结构:
这是我的代码
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
组件的副标题是 "news"。
我不知道如何获取 ArticlePageTemplate
的文章组件,因此我可以将它们添加到我在 lucene 中的搜索查询中。
如有任何建议,我们将不胜感激。
注:
ArticlesComponent
的数据源可能会更改,因此它并不总是 ArticlesPageTemplate
的 child。
更新(2015 年 9 月 11 日)
我尝试了 Richard 建议的方法,但没有用。
var articles = SearchService
.PerformSearch<ArticleResultItem>("/sitecore/content", "ArticlePageTemplate")
.Where(item => item.SubHeader == "News").ToList();
使用上面的查询不会产生任何结果,但使用下面的查询 returns 会得到结果,但它检索的是 ArticleComponent 而不是 ArticlePageTemplate。
var articles = SearchService
.PerformSearch<ArticleResultItem>("/sitecore/content"
.Where(item => item.SubHeader == "News").ToList();
解决方案:
计算字段有效。请参阅下面 link 中的 VisualizationField.cs:
您需要创建一个自定义 class 允许您在您的字段上进行过滤,您可以将其基于 SearchResultItem
class.
所以像这样:
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....
}
}
我可以在这里看到两种方法:
为 Article 组件子标题字段构建一个 'computed field'。 您可以设置它,以便将索引配置为查找该组件在具有 ArticlePageTemplate 模板的项目上,并将子标题值计算到索引中。这实质上使索引认为子标题字段实际上是 ArticlePageTemplate 项目上的一个字段。然后你可以在索引上做一个常规的搜索。
查找组件的参考页。 在这种情况下,您搜索组件的索引(不是 ArticlePageTemplate),如果您可以依赖您的文件夹结构并且您没有 re-use 跨页面,然后您可以只抓取任何搜索结果的 parent 页面。 (item.Parent.Parent,在您的示例结构中)
更新:计算字段的一些链接:
我有一个名为 ArticlePageTemplate
的页面模板。此 ArticlePageTemplate
包含一个名为 Articles
的组件。 Article
组件具有名为 Header
、SubHeader
、Date
和 Content
的数据字段。
ArticlesPageTemplate
的演示文稿详情
在 sitecore 8 中使用 Lucene。如何获取所有包含 Article 组件的 ArticlePageTemplate,其中 Article 组件的子标题中的值为 "News"。
站点核心结构:
这是我的代码
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
组件的副标题是 "news"。
我不知道如何获取 ArticlePageTemplate
的文章组件,因此我可以将它们添加到我在 lucene 中的搜索查询中。
如有任何建议,我们将不胜感激。
注:
ArticlesComponent
的数据源可能会更改,因此它并不总是 ArticlesPageTemplate
的 child。
更新(2015 年 9 月 11 日)
我尝试了 Richard 建议的方法,但没有用。
var articles = SearchService
.PerformSearch<ArticleResultItem>("/sitecore/content", "ArticlePageTemplate")
.Where(item => item.SubHeader == "News").ToList();
使用上面的查询不会产生任何结果,但使用下面的查询 returns 会得到结果,但它检索的是 ArticleComponent 而不是 ArticlePageTemplate。
var articles = SearchService
.PerformSearch<ArticleResultItem>("/sitecore/content"
.Where(item => item.SubHeader == "News").ToList();
解决方案:
计算字段有效。请参阅下面 link 中的 VisualizationField.cs:
您需要创建一个自定义 class 允许您在您的字段上进行过滤,您可以将其基于 SearchResultItem
class.
所以像这样:
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....
}
}
我可以在这里看到两种方法:
为 Article 组件子标题字段构建一个 'computed field'。 您可以设置它,以便将索引配置为查找该组件在具有 ArticlePageTemplate 模板的项目上,并将子标题值计算到索引中。这实质上使索引认为子标题字段实际上是 ArticlePageTemplate 项目上的一个字段。然后你可以在索引上做一个常规的搜索。
查找组件的参考页。 在这种情况下,您搜索组件的索引(不是 ArticlePageTemplate),如果您可以依赖您的文件夹结构并且您没有 re-use 跨页面,然后您可以只抓取任何搜索结果的 parent 页面。 (item.Parent.Parent,在您的示例结构中)
更新:计算字段的一些链接: