Sitecore for Developers
Sitecore Drop List Faceting Phrase Space Issue with Solr Search
Note - The Sitecore version this code was tested in is Sitecore.NET 8.1 (rev. 160302) and Solr search version is solr-5.1.0This blog will explain Faceting functionality on index fields in Sitecore. Sitecore search will use faceting functionality to split or divide the search results into different categories. Sitecore Faceting will make the web site users to navigate or explore through the search results categories. Recently in a project, we were tasked to categorize the search results into different categories and display the categories on the page for the users to navigate though.We have 3 different areas of category interest to show to the end user. So I created 3 different items and feed those category items to a drop list (not drop link where we get the item ID). In Sitecore Drop list stores the name of the item and we cannot retrieve the actual selected item.Our categories are
- Learning Centers
- ABC
- XYZ
The Sitecore Drop list will have the above values and We apply faceting based on the drop list with the following API code.
var predicate10 = PredicateBuilder.True();predicate10 = predicate10.And(p => p.Content.Contains(searchText));predicate10 = predicate10.And(p => p.Path.Contains("Web/Homepage"));var query10 = context.GetQueryable().Where(predicate10).FacetOn(s => s.SearchType, 1);totalCount = query10.Count();List Results10 = query10.Skip((page - 1) * count).Take(count).ToList();FacetResults fr = query10.GetResults().Facets;
In the above code, SearchType is the drop list index field which is defined in SearchResultModel as follows. Search result type is the name of the field and it is being indexed as text as it gives just name of the item.
public class SearchResultModel : SearchResultItem{[IndexField("search_result_type_t")]public string SearchType { get; set; }}
The above Code was faceting on drop list in Sitecore fine but when the faceted category contains a space in between, it splits the facet category into two different facets. Below screenshot shows how facet splits Learning Center facet into two separate facets.So, after some research , found out that the default index field type in Solr is tokenized which means that it will split up the string in your index. So, we need to make that index type to be untokenized and index field needs to be treated as a regular string but not tokenized index. So, I came across some blogs and found that the best way to implement this would be by creating a custom untokenized computed field to resolve this space issue.Follow the below steps for the resolution of the issue.
- Create a computed field class in project implementing the Sitecore interface IComputedIndexField(import name space ContentSearch.ComputedFields)
namespace HorizontalIntegration.Services.Search{public class SearchCategoryComputedField : IComputedIndexField{public object ComputeFieldValue(IIndexable indexable){if (indexable == null){Log.Warn(this + " : not indexable : " + indexable.GetType(), this);throw new ArgumentNullException("indexable");}SitecoreIndexableItem scIndexable = indexable as SitecoreIndexableItem;Item item = (Item)scIndexable;if (String.Compare(item.Database.Name, "core", StringComparison.OrdinalIgnoreCase) == 0){return false;}return item.Fields["Search Result Type"];}}}
- Add a patch to configuration by creating a new .config file in Website\App_config\Include directory and add the following code to the config file. the following configuration.
<defaultSolrIndexConfigurationtype="Sitecore.ContentSearch.SolrProvider.SolrIndexConfiguration, Sitecore.ContentSearch.SolrProvider"><fieldshint="raw:AddComputedIndexField"><fieldfieldName="plaincategory" returnType="string">xxx.Services.Search.SearchCategoryComputedField, xxx.Services
Or we can directly add the following configuration line to raw:AddComputedIndexField section of solr configuration file Include\Sitecore.ContentSearch.Solr.DefaultIndexConfiguration.config
<field fieldName="plaincategory" returnType="string">xxx.Services.Search.SearchCategoryComputedField, xxx.Services</field>
Note that HorizontalIntegration.Services is the name of my assembly and HorizontalIntegration.Services.Search is namespace.
- Rebuild the index
- Open Sitecore desktop
- Open Indexing manager and click on Sitecore >control Panel >Indexing >Indexing Manager.
- Check the indexes that needs to be rebuilt and click Rebuild.
- Now, we have a new computed field for the drop list (Search Result Type) from Sitecore. We are not done yet. We need to change the code and provide this newly computed field to the FacetOn method in the above code like shown below.
var query = context.GetQueryable<SearchResultModel>().Where(predicate10).FacetOn(s => s["plaincategory"], 1);Now, the query will return the only 3 facets and Learning Center will be one of them and considered as one facet instead of two like shown below.