在 Sitecore 里使用 Solr 搜索 SortOrder 关联的 Item

  • 在 Sitecore 里使用 Solr 搜索 SortOrder 关联的 Item已关闭评论
  • 101 次浏览
  • A+
所属分类:.NET技术
摘要

sitecore 的配置信息文件可直接丢进 <Instance>App_Config 下,sitecore 会自动检测配置文件更新并加载到内存中。
通常情况下,配置信息文件是放在 <Instance>App_ConfigInclude<Project> 下,<Project> 为你项目名。


在 C# 使用 Solr 搜索

sitecore 的配置信息文件可直接丢进 <Instance>App_Config 下,sitecore 会自动检测配置文件更新并加载到内存中。
通常情况下,配置信息文件是放在 <Instance>App_ConfigInclude<Project> 下,<Project> 为你项目名。


通过配置启用 SortOrder 字段并获取 SortOrder

sitecore 默认是移除了 SortOrder 字段的,不过可通过打个补丁修改配置信息,如下配置 xml 启用 SortOrder 字段。
但是这种启用 SortOrder 字段有个不好的地方,当字段值为空时,在 Solr 里是找不到此字段的,且值类型为 string 类型。

EnableSortOrder_Patch.config
<?xml version="1.0" encoding="utf-8"?> <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">   <system.web>   </system.web>   <sitecore>       <contentSearch>           <indexConfigurations>               <defaultSolrIndexConfiguration type="Sitecore.ContentSearch.SolrProvider.SolrIndexConfiguration, Sitecore.ContentSearch.SolrProvider">                   <documentOptions type="Sitecore.ContentSearch.SolrProvider.SolrDocumentBuilderOptions, Sitecore.ContentSearch.SolrProvider">                       <exclude hint="list:AddExcludedField">                           <__SortOrder>                               <patch:delete />                           </__SortOrder>                       </exclude>                   </documentOptions>               </defaultSolrIndexConfiguration>           </indexConfigurations>       </contentSearch>   </sitecore> </configuration> 
C# Code
// ./SearchResultModel.cs using Sitecore.ContentSearch;  public class SearchResultModel {     [IndexField(BuiltinFields.Name)]     public virtual string ItemName { get; set; }      // 注意此处需要填 SortOrder 的 Item name, 而不是 Title(通常在 sitecore 里直接看到就是 Title) 或者 Display Name     // 可通过它的 ID 找出证实一下 {BA3F86A2-4A1C-4D78-B63D-91C2779C1B5E}     // 或通过路径:/sitecore/templates/System/Templates/Sections/Appearance/Appearance/__Sortorder     [IndexField("__Sortorder")]     public virtual int SortOrder { get; set; }      [IndexField(BuiltinFields.LatestVersion)]     [ScriptIgnore]     public virtual bool IsLatestVersion { get; set; } }  // ----------------------------------------------  // ./Sample.cs using Sitecore.ContentSearch; using Sitecore.Globalization; using Sitecore.ContentSearch.Linq.Utilities;      var indexName = "sitecore_web_index"; var language = Sitecore.Globalization.Language.Parse("en"); using (IProviderSearchContext context = ContentSearchManager.GetIndex(indexName) {     var predicate = PredicateBuilder.True<SearchResultModel>();     if (!Sitecore.Context.PageMode.IsNormal)         predicate = predicate.And(z => z.IsLatestVersion);      predicate = predicate.And(z => z.Language.Equals(language.Name, StringComparison.OrdinalIgnoreCase));      var query = context.GetQueryable<SearchResultModel>()         .Filter(predicate);      // sitecore 排序的规则为:先按 SortOrder 升序排序,再按 Item name 升序排序     query = query         .OrderBy(z => z.SortOrder)         .ThenBy(z => z.ItemName);      return query.Select(x => x.Item)?.GetResults().Hits.Select(z => z.Document); } 

*通过使用通过使用 IComputedIndexField 的获取 SortOrder 的方法

此方法与前面不同的地方在于,当字段值为空时,在 Solr 里仍然可以搜索到此字段,且值为 100,同时值类型为 int 类型。推荐使用这种方式。

AddSortOrderField_Patch.config
<?xml version="1.0" encoding="utf-8"?> <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">   <system.web>   </system.web>   <sitecore>     <contentSearch>       <indexConfigurations>         <defaultSolrIndexConfiguration type="Sitecore.ContentSearch.SolrProvider.SolrIndexConfiguration, Sitecore.ContentSearch.SolrProvider">           <documentOptions>             <fields hint="raw:AddComputedIndexField">               <field fieldName="SortOrder" returnType="int">LinkReit.Feature.Content.ChannelCard.ComputedFields.SortOrderField, LinkReit.Feature.Content.ChannelCard</field>             </fields>           </documentOptions>         </defaultSolrIndexConfiguration>       </indexConfigurations>     </contentSearch>   </sitecore> </configuration> 
C# Code
// ./SortOrderField.cs  using Sitecore.Data.Items; using Sitecore.ContentSearch; using Sitecore.ContentSearch.ComputedFields;  public class SortOrderField : IComputedIndexField {     public object ComputeFieldValue(IIndexable indexable)     {         var item = (Item)(indexable as SitecoreIndexableItem);         if (item == null) return null;                  return item.Appearance.Sortorder;     }      public string FieldName { get; set; }      public string ReturnType { get; set; } }  // ----------------------------------------------  // ./SearchResultModel.cs using Sitecore.ContentSearch;  public class SearchResultModel {     [IndexField(BuiltinFields.Name)]     public virtual string ItemName { get; set; }      // 此处 IndexFieldAttribute 构造参数需要填写的是你配置的 SortOrder 的 fieldName     [IndexField("SortOrder")]     public virtual int SortOrder { get; set; }      [IndexField(BuiltinFields.LatestVersion)]     [ScriptIgnore]     public virtual bool IsLatestVersion { get; set; } }  // ----------------------------------------------  // ./Sample.cs using Sitecore.ContentSearch; using Sitecore.Globalization; using Sitecore.ContentSearch.Linq.Utilities;      var indexName = "sitecore_web_index"; var language = Sitecore.Globalization.Language.Parse("en"); using (IProviderSearchContext context = ContentSearchManager.GetIndex(indexName) {     var predicate = PredicateBuilder.True<SearchResultModel>();     if (!Sitecore.Context.PageMode.IsNormal)         predicate = predicate.And(z => z.IsLatestVersion);      predicate = predicate.And(z => z.Language.Equals(language.Name, StringComparison.OrdinalIgnoreCase));      var query = context.GetQueryable<SearchResultModel>()         .Filter(predicate);      // sitecore 排序的规则为:先按 SortOrder 升序排序,再按 Item name 升序排序     query = query         .OrderBy(z => z.SortOrder)         .ThenBy(z => z.ItemName);      return query.Select(x => x.Item)?.GetResults().Hits.Select(z => z.Document); }