Faceted Searching
Facet Searches are search summaries – they provide a breakdown of result counts for each of the defined categories/facets.
Defining Facets
You define facets inside the define_index method, within your model. To specify that a field or attribute should be considered as a facet, explicitly label it using the :facet symbol.
define_index do
# ...
indexes author.name, :as => :author, :facet => true
# ...
has category_id, :facet => true
end
You cannot use custom SQL statements as string facet sources. Thinking Sphinx is unable to interpret the SQL within the context of the model, and strings can’t be stored as strings when they are attributes in Sphinx.
Even if you define your facet as a field, Thinking Sphinx duplicates it into an attribute, because facets are essentially grouped searches, and grouping can only be done with attributes.
Querying Facets
Facets are available through the facets class method on all ActiveRecord models that have Sphinx indexes, and are returned as a subclass of Hash. In this case
we’re using the Article model:
Article.facets # =>
{
:author => {
"Sherlock Holmes" => 3,
"John Watson" => 10
},
:category_id => {
12 => 4,
42 => 7,
47 => 2
}
}
The facets method accepts the same options as the search method.
Article.facets 'pancakes'
Article.facets :conditions => {:subject => 'pancakes'}
You can also explicitly request just certain facets:
Article.facets :facets => [:author]
Below is a basic example of rendering the facet search results in a view:
<% @facets.each do |facet, values| %>
<h5><%= facet %></h5>
<ul>
<% values.each do |key, count| %>
<li><%= link_to key, :overwrite_params => {facet => key} %></li>
<% end %>
</ul>
<% end %>
To retrieve the ActiveRecord object results based on a selected facet, you can use the for method on a facet search result.
Article.facets('pancakes').for(:author => "Pat Allan")
Global Facets
Faceted searches can be made across all indexed models, using the same arguments.
ThinkingSphinx.facets 'pancakes'
By default, Thinking Sphinx does not request all possible facets, only those common to all models. If you don’t have any of your own facets, then this will just be the class facet, providing a summary of the matches per model.
ThinkingSphinx.facets 'pancakes' # =>
{
:class => {
'Article' => 13,
'User' => 3,
'Recipe' => 23
}
}
To disable the class facet, just set :class_facet to false.
ThinkingSphinx.facets 'pancakes', :class_facet => false
And if you want absolutely every facet defined to be returned, whether or not they exist in all indexed models, set :all_facets to true.
ThinkingSphinx.facets 'pancakes', :all_facets => true