【问题标题】:EPiServer Search only search for base typesEPiServer Search 仅搜索基本类型
【发布时间】: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


【解决方案1】:

看起来标准的页面过滤器没有实现这一点。 但是您应该能够通过扩展 EPiServer.Filters.IPageFilter 类来创建自己的过滤器。并在您的文件过滤器中使用 Type.IsSubclassOf 检查页面的类型。

【讨论】:

    【解决方案2】:

    我认为问题在于索引。在 ContentSearchHandler 类中,GetItemType(Type contentType) 方法将所有基本类型添加到 ItemType 字段。由于该方法是公共虚拟方法,因此您应该能够将其替换为您自己在 StructureMap 容器中的实现,该容器仅返回基本类型。

    【讨论】:

      猜你喜欢
      • 2012-12-04
      • 1970-01-01
      • 2021-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-21
      • 1970-01-01
      相关资源
      最近更新 更多