【发布时间】:2016-12-08 10:27:50
【问题描述】:
我的搜索功能中有一个 pagetypefilter,并且有一个页面 b 继承自页面 a 的场景。当我检查过滤器列表中的页面选项时,我仍然会点击页面 b 的类型。是否可以只搜索 EPiServer 搜索中的基类型?
在我的例子中是页面 b:
public class b : a
{
public virtual string ExternalUrl { get; set; }
[ScaffoldColumn(false)]
[JsonIgnore]
[Searchable(false)]
public virtual string Id { get; set; }
}
和页面一个
public class a: SitePageData
{
[Display(GroupName = SystemTabNames.Content, Order = 4)]
[CultureSpecific]
[UIHint(UIHint.Textarea)]
public virtual String Intro { get; set; }
[Display(GroupName = SystemTabNames.Content, Order = 5)]
[CultureSpecific]
public virtual XhtmlString MainBody { get; set; }
[Display(GroupName = SystemTabNames.Content, Order = 6)]
public virtual ContentArea MainContentArea { get; set; }
[Display(GroupName = SystemTabNames.Content, Order = 8)]
public virtual RelatedInformationBlock RelatedInformation { get; set; }
[Display(GroupName = SystemTabNames.Settings, Order = 9000)]
public virtual SocialMediaShareLinksBlock ShareLinks { get; set; }
public override void SetDefaultValues(ContentType contentType)
{
base.SetDefaultValues(contentType);
ShareLinks.ShowFacebookShareLink = true;
ShareLinks.ShowTwitterShareLink = true;
ShareLinks.ShowLinkedInShareLink = true;
}
}
在我的 pagetypefilter 中,我只检查了 a 类的选项
这是完整的查询
private IQueryExpression CreateQuery(SearchQuery searchQuery)
{
var query = new GroupQuery(LuceneOperator.AND);
if (!(searchQuery.SearchText.StartsWith("\"") && searchQuery.SearchText.EndsWith("\"")))
searchQuery.SearchText = searchQuery.SearchText.Replace(" ", "* ") + "*";
if (!string.IsNullOrWhiteSpace(searchQuery.SearchText))
{
var searchTextQuery = new GroupQuery(LuceneOperator.OR);
//searchTextQuery.QueryExpressions.Add(new TermBoostQuery(searchQuery.SearchText, Field.Created,10000F));
searchTextQuery.QueryExpressions.Add(new TermBoostQuery(searchQuery.SearchText, Field.Title, 1F));
searchTextQuery.QueryExpressions.Add(new TermBoostQuery(searchQuery.SearchText, Field.ItemType, 0.2F));
searchTextQuery.QueryExpressions.Add(new TermBoostQuery(searchQuery.SearchText, Field.DisplayText, 0.1F));
searchTextQuery.QueryExpressions.Add(new FieldQuery(searchQuery.SearchText));
query.QueryExpressions.Add(searchTextQuery);
}
var virtualPathQueryGroup = new GroupQuery(LuceneOperator.OR);
if (searchQuery.RootsFilter.IsNullOrEmpty())
{
var contentRootQuery = new VirtualPathQuery();
contentRootQuery.AddContentNodes(ContentReference.StartPage);
virtualPathQueryGroup.QueryExpressions.Add(contentRootQuery);
var contentRootQuery2 = new VirtualPathQuery();
contentRootQuery2.AddContentNodes(SiteDefinition.Current.GlobalAssetsRoot);
virtualPathQueryGroup.QueryExpressions.Add(contentRootQuery2);
var contentRootQuery3 = new VirtualPathQuery();
contentRootQuery3.AddContentNodes(SiteDefinition.Current.ContentAssetsRoot);
virtualPathQueryGroup.QueryExpressions.Add(contentRootQuery3);
}
else
{
virtualPathQueryGroup.QueryExpressions.Clear();
foreach (var root in searchQuery.RootsFilter)
{
var contentRootQuery = new VirtualPathQuery();
contentRootQuery.AddContentNodes(root);
virtualPathQueryGroup.QueryExpressions.Add(contentRootQuery);
}
}
query.QueryExpressions.Add(virtualPathQueryGroup);
if (searchQuery.PageTypesFilter.Any() || searchQuery.MediaTypesFilter.Any())
{
var contentQuery = new GroupQuery(LuceneOperator.OR);
if (searchQuery.MediaTypesFilter.Any())
{
var mediaContentQuery = new GroupQuery(LuceneOperator.OR);
foreach (var type in searchQuery.MediaTypesFilter)
mediaContentQuery.QueryExpressions.Add(new TypeContentQuery(type));
contentQuery.QueryExpressions.Add(mediaContentQuery);
}
if (searchQuery.PageTypesFilter.Any())
{
var pageContentQuery = new GroupQuery(LuceneOperator.AND);
var pageContentQueryTypes = new GroupQuery(LuceneOperator.OR);
foreach (var type in searchQuery.PageTypesFilter)
pageContentQueryTypes.QueryExpressions.Add(new TypeContentQuery(type));
pageContentQuery.QueryExpressions.Add(new FieldQuery(CultureInfo.CurrentUICulture.Name, Field.Culture));
pageContentQuery.QueryExpressions.Add(pageContentQueryTypes);
contentQuery.QueryExpressions.Add(pageContentQuery);
}
query.QueryExpressions.Add(contentQuery);
}
if (!searchQuery.CategoriesFilter.IsNullOrEmpty())
{
var categoriesToCommaList = String.Join(",", searchQuery.CategoriesFilter);
var categoryQuery = new ContentCategoryQuery(CategoryList.Parse(categoriesToCommaList), LuceneOperator.OR);
query.QueryExpressions.Add(categoryQuery);
}
// // The access control list query will remove any files the user doesn't have read access to
AccessControlListQuery aclQuery = new AccessControlListQuery();
aclQuery.AddAclForUser(PrincipalInfo.Current, HttpContext.Current);
query.QueryExpressions.Add(aclQuery);
return query;
}
最后是 Typequery 本身:
public class TypeContentQuery : IQueryExpression
{
private readonly Type contentType;
public TypeContentQuery(Type contentType)
{
if (contentType == null)
{
throw new ArgumentNullException("contentType");
}
this.contentType = contentType;
}
public string GetQueryExpression()
{
var typeExpression = "\"" + ContentSearchHandler.GetItemTypeSection(contentType) + "\"";
return new FieldQuery(typeExpression, Field.ItemType).GetQueryExpression();
}
}
【问题讨论】:
-
这是否意味着您要排除所有派生类,在您的情况下,
class b根本不应该在您的结果中列出?我们还需要了解您如何构造 a、b 对象。 -
没错。编辑了我的问题
-
嗯,通常 OOTB 我会拒绝。但是您确实拥有
contentSearchHandler.GetContent<YourType>(xxx);,并且可以根据该结果来反映结果。
标签: c# .net inheritance lucene.net episerver