Before processing the practical example here I am sharing
some term and definition so that we can easily understand what exactly Facet
Search is.
some term and definition so that we can easily understand what exactly Facet
Search is.
What is Faceted Search?
From the user perspective, faceted search breaks up search
results into multiple categories, typically showing counts for each, and allows
the user to “drill down” or further restrict their search results
based on those facets.
results into multiple categories, typically showing counts for each, and allows
the user to “drill down” or further restrict their search results
based on those facets.
Why Faceted Search?
To control the
presentation of search results. In the end, it’s about helping the user find
the right information. Faceted search gives a user the power to create an
individualized navigation path, drilling down through successive refinements to
reach the right document. This more effectively mirrors the intuitive thought
patterns of most users. Faceted search has become an expected feature,
particularly for commerce sites.
presentation of search results. In the end, it’s about helping the user find
the right information. Faceted search gives a user the power to create an
individualized navigation path, drilling down through successive refinements to
reach the right document. This more effectively mirrors the intuitive thought
patterns of most users. Faceted search has become an expected feature,
particularly for commerce sites.
How It Works
Faceted search is performed in several parts:
Index: to each
document in the index, add tags to specify a value for each facet. For example,
for each book in the index, tag it with the type of material and the price
range.
document in the index, add tags to specify a value for each facet. For example,
for each book in the index, tag it with the type of material and the price
range.
Search results:
for every search, the solr server returns a count of how many matching
documents were tagged with each value within each facet. For example, if the
query was for “books,” you might find out that in the facet
“type of material,” your index contains 13 science fiction books, 15
romance novels, and 10 cookbooks; and in the price facet, there are 5 books
under $10, 200 books from $10-19.99, and so on.
for every search, the solr server returns a count of how many matching
documents were tagged with each value within each facet. For example, if the
query was for “books,” you might find out that in the facet
“type of material,” your index contains 13 science fiction books, 15
romance novels, and 10 cookbooks; and in the price facet, there are 5 books
under $10, 200 books from $10-19.99, and so on.
Query: you can
include facet values as query criteria. For example, you can write a query that
returns only the romance novels under $10.
include facet values as query criteria. For example, you can write a query that
returns only the romance novels under $10.
Web page: use the
facets and document counts returned by the server to create a set of facet
links on your web page, like the example shown above. Then construct queries to
be activated by each facet link, passing in the appropriate values—say,
querying only for romance novels when the user clicks the “Romance
(15)” link
facets and document counts returned by the server to create a set of facet
links on your web page, like the example shown above. Then construct queries to
be activated by each facet link, passing in the appropriate values—say,
querying only for romance novels when the user clicks the “Romance
(15)” link
Implementing Faceting with Solr
It’s relatively simple to get faceting information from
Solr, as there are few prerequisites. Solr offers the following types of
faceting, all of which can be requested with no prior configuration:
Solr, as there are few prerequisites. Solr offers the following types of
faceting, all of which can be requested with no prior configuration:
·
Field
faceting – retrieve the counts for all terms, or just the top terms in any
given field. The field must be indexed.
Field
faceting – retrieve the counts for all terms, or just the top terms in any
given field. The field must be indexed.
·
Query
faceting – return the number of documents in the current search results
that also match the given query.
Query
faceting – return the number of documents in the current search results
that also match the given query.
·
Date
faceting – return the number of documents that fall within certain date
ranges
Date
faceting – return the number of documents that fall within certain date
ranges
Before processing the practical example here I am sharing
some term and definition so that we can easily understand what exactly Facet
Search is.
some term and definition so that we can easily understand what exactly Facet
Search is.
Practical Example:
This example is for person search.
Suppose we have person template in sitecore with some field’s
and we already indexed that particular field including the facet field for
example,
and we already indexed that particular field including the facet field for
example,
First name
Last name
Sectors : this is reference field and we need
to facet on this field at the time of searhing.
to facet on this field at the time of searhing.
We have created class named person
public
class Person
class Person
{
[IndexField(“firstname_t”)]
public string
Firstname {
get;
set;
}
Firstname {
get;
set;
}
[IndexField(“lastname_t”)]
public string
sector { get; set; }
sector { get; set; }
[IndexField(“sector”)]
}
Then created person
search class as below
search class as below
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Sitecore.ContentSearch;
using Sitecore.ContentSearch.Linq;
using Sitecore.ContentSearch.Utilities;
using Sitecore.Data;
namespace XYZ
{
public class
PeopleSearch
PeopleSearch
{
private
static ISearchIndex _index;
static ISearchIndex _index;
private
List<ID> _templateRestrictions = new List<ID>();
List<ID> _templateRestrictions = new List<ID>();
private
List<string> _facets = new List<string>();
List<string> _facets = new List<string>();
private
static ISearchIndex Index
static ISearchIndex Index
{
get {
return _index ??
return _index ??
(_index =
ContentSearchManager.GetIndex(Sitecore.Configuration.Settings.GetSetting(“SearchIndex.Index”)));
}
}
public
List<ID> TemplateRestrictions
List<ID> TemplateRestrictions
{
get {
return _templateRestrictions; }
return _templateRestrictions; }
set {
_templateRestrictions = value; }
_templateRestrictions = value; }
}
public
List<string> Facets
List<string> Facets
{
get {
return _facets; }
return _facets; }
set {
_facets = value; }
_facets = value; }
}
public SearchResults<Person>
Search(string searchTerm)
Search(string searchTerm)
{
//
Create search context – required for searching
Create search context – required for searching
using
(var context = Index.CreateSearchContext())
(var context = Index.CreateSearchContext())
{
// Setup a predicate builder as an easy way to build up predicate
var predicate = PredicateBuilder.True<Person>();
// Restrict search to limited number of templates (only person items)
using an Or on the predicate
predicate = TemplateRestrictions.Aggregate(predicate, (current, t) =>
current.Or(p => p.TemplateId == t));
// Use filter and get an IQueryable
IQueryable<Person> query =
context.GetQueryable<Person>().Filter(predicate);
// now we can perform filter if we have a search term
if (!string.IsNullOrEmpty(searchTerm))
{
query = query.Where(i => i.Firstname.Equals(searchTerm).Boost(10) ||
i.Surname.Equals(searchTerm).Boost(20));
}
// Apply facets to query
if (Facets.Any())
{
// Go through and set up facets on the IQueryable
query = Facets.Aggregate(query, (current, facetName) =>
current.FacetOn(c => c[facetName]));
}
// Call query and return results
return query.GetResults();
}
}
}
}
Here we are calling search function:
Sitecore.Data.ID templateId = new Sitecore.Data.ID(“{your
value”);
value”);
PeopleSearch peopleSearch = new PeopleSearch();
peopleSearch.TemplateRestrictions.Add(templateId);
// Add a
facet
facet
peopleSearch.Facets.Add(“sector”);
// get
results
results
SearchResults<Person> peopleResults = peopleSearch.Search(“”);
StringBuilder outputBuilder = new StringBuilder();
outputBuilder.Append(“<p>***********Results*************************************</p>”);
outputBuilder.Append(“<p>Found: ” +
peopleResults.TotalSearchResults + ” results </p>”);
// Display
hits
hits
foreach
(var hit in peopleResults.Hits)
(var hit in peopleResults.Hits)
{
outputBuilder.Append(“<p>Name:
” + hit.Document.Firstname + ” ” + hit.Document.lastname +
“</p>”);
” + hit.Document.Firstname + ” ” + hit.Document.lastname +
“</p>”);
if
(hit.Document.Role != null)
(hit.Document.Role != null)
{
foreach (var sector in hit.Document.sector)
{
outputBuilder.Append(“<p>Role Sitecore Id:” + sector +
“</p>”);
}
}
outputBuilder.Append(“<p>****************************</p>”);
}
outputBuilder.Append(“<p>***********Facets*************************************</p>”);
// Loop
through facet categories
through facet categories
List<FacetCategory> facetCategories =
peopleResults.Facets.Categories;
foreach
(var category in facetCategories)
(var category in facetCategories)
{
outputBuilder.Append(“<p>Facet Category Name: ” +
category.Name + “</p>);
foreach (var value in category.Values)
{
outputBuilder.Append(“<p>Value: ” + value.Name + “</p>”);
outputBuilder.Append(“<p>Number of results with this value:
” + value.Aggregate + “</p>”);
outputBuilder.Append(“<p>****************************</p>”);
}
}
lblOutput.Text =
outputBuilder.ToString();
outputBuilder.ToString();
here is the output
Actual Output
***********Results*************************************
Found: 5 results
Name: test
sector Sitecore Id:501703e57c884ee586793e90650e28cd
sector Sitecore Id:bdf6b678a6fd43ebab6edb22b98958a4
sector Sitecore Id:332e33a9854a44628555272cd4b91ad2
****************************
Name: test
sector Sitecore Id:96352039bf3440d183a8fd92e14a0b72
sector Sitecore Id:332e33a9854a44628555272cd4b91ad2
sector Sitecore Id:963970baae63414da6d44777c103cff9
***********Facets*************************************
Facet Category Name: sector
Value: 332e33a9854a44628555272cd4b91ad2
Number of results with this value: 3
****************************
Value: 501703e57c884ee586793e90650e28cd
Number of results with this value: 3
****************************
I took some code from fusionworkshop blog.