在 C# 使用 Solr 搜索 sitecore 的配置信息文件可直接丟進 <Instance>\App_Config 下,sitecore 會自動檢測配置文件更新並載入到記憶體中。 通常情況下,配置信息文件是放在 <Instance>\App_Config\Include\<Project> 下,< ...
在 C# 使用 Solr 搜索
sitecore 的配置信息文件可直接丟進
<Instance>\App_Config
下,sitecore 會自動檢測配置文件更新並載入到記憶體中。
通常情況下,配置信息文件是放在<Instance>\App_Config\Include\<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.Language)]
public virtual string Language { 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.Language)]
public virtual string Language { 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);
}