CODE FACETING WITHIN THE SITECORE CONTENT SEARCH
I was really impressed with what we were able to achieve in a recent project by simply leveraging the facets functionality of the Sitecore Lucene and SOLR integration. We used this functionality to produce a list of search filters, just like the ones seen on most e-commerce websites.
While performing a search within the content search you are able to call the .FacetOn() method, the first property for this method is the index field you wish to facet on, you do this via a simple LINQ link expression: (x => x.PropertyName).
The second parameter to FacetOn() is optional, however it is an integer and it’s a min count. What does that mean? It means that if you provide a min count, your facet results will only bring back facets that have been found >= to the min count set by you, I believe the default is 0.
The final call to the method will look something like: .FacetOn(x => x.PropertyName, 1);
You are able to chain these method calls to facet on different fields within the same query.
Let’s have a look at some code:
using (IProviderSearchContext searchContext = ContentSearchManager.GetIndex("sitecore_web_index").CreateSearchContext())
{
//get results with facets
var results = searchContext.GetQueryable()
.OrderBy(i => i.CreatedDate)
.Skip(skip)
.Take(pageSize)
.FacetOn(t => t["categories"], 1) //facet on categories field (this could be any field that you wish to facet on).
.FacetOn(t => t["other_field"], 1)
.GetResults();
//bind your results to a repeater or something...
//Repeater.DataSource = results.Hits;
//Repeater.DataBind();
//check if we have any facet categories
if (results.Facets != null && results.Facets.Categories.Any())
{
//select our facet category from results
FacetCategory categories = results.Facets.Categories.First(x => x.Name.Equals("categories"));
//if we have our category and it has values
if (categories != null && categories.Values.Any())
{
//loop through them
foreach (FacetValue facet in categories.Values)
{
//how many times the facet was found within the result set (categories field)
int facetCount = facet.AggregateCount;
//the facet name, this value will depend on what you faceted on, in our case categories is a
//multi-list field which means the .Name property will be the id of the category within sitecore.
string facetValue = facet.Name;
}
}
}
}
The above code will get you started. We could refactor parts of this code for example, the extraction of the facet properties and make it a little more generic/reusable.
You aren’t limited to set properties you can facet on, you are able to create your own SearchResultItem and add your own properties to query and facet on (a post on custom result items will follow shortly). Furthermore, you are not limited to a single facet category, you are able to facet on as many properties as you want, however this will leave you with more FacetCategories that will need processing.