Facet Search Implementation Tips

I recently added a facet search capability to a website. It’s really cool! Facet search allows the user to apply filters to a collection of data in order to narrow down the results. Implementation is more complicated than it initially sounds.
Assuming the data is stored in a database, one way to implement facet searching is to repeatedly call the database with a new query whenever a filter is added or removed. This way can get complicated, but it’s possible. It seems like it may be a little slow too. Here are a few links with details on how to implement it: http://stackoverflow.com/questions/8300675/php-navigation-with-filtershttp://ivaldi.nl/2012/05/seo-friendly-faceted-search-1/
The other way to implement facet searching is to load all of the data once when the page loads. When a filter is activated or deactivated, the filter is applied to the stored data and the results updated. Loading all of the data at once may be a little slow, but once the data is all loaded the filtering goes pretty quick. You can hook in ajax, so that when the filter is activated or deactivated, the results immediately update without a page reload. The site I was adding this to is pretty complex and to reload the page each time wouldn’t be the greatest user experience. There were a couple of examples I followed for the implementation. The main one being: http://eikes.github.com/facetedsearch/

Other helpful examples were:

The facet menu had 3 facets. One was a list of checkboxes. The other two were a series of links where only one link in each facet could be active at a time.
I made a template file for the general outline of the facet menu, a script file to control features of the facet menu itself, such as hide a facet when only one choice is allowed and updating a current selections div. It sat on top of the facetedsearch example script. That file needed a few changes in order to accomodate the data being filtered and to blend the results into the way the page was displaying the results.
I also changed the way the counts were displayed. I took out the + and found the counts for each option based on the filtered data. That was a little tricky, but worked out good.
Another key piece in making the facet search run smoothly is to add a hash tag at the end of your url with parameters for the currently set filters. ex: www.abc.com/#x=1&y=2
Doing this ensures the back/forward buttons navigate smoothly. Some helpful links about that are:

I ended up using this plugin for Internet Explorer 7 to work properly: http://benalman.com/projects/jquery-hashchange-plugin/

For browsers supporting history.pushback, you can just do:
window.history.pushState({path : pageurl}, ”, pageurl); to add the hash tag.

For browsers not supporting history.pushback, you do:
window.location.hash = filter_str;

To make it work, you do:
var originalHash = window.location.hash;
if (window.history && window.history.pushState) {
window.addEventListener(“popstate”, function(e) {

var newHash = window.location.hash;
if(newHash != originalHash) {
//get the filters from the url, apply them & update the results

originalHash = newHash;
For Internet Explorer 7:
$(window).hashchange( function(){
var newHash = location.hash;
if(newHash != originalHash) {
originalHash = newHash;
//get the filters from the url, will need to compare them against current filter,
apply them if different, update the results

// Since the event is only triggered when the hash changes, we need to trigger
// the event now, to handle the hash the page may have loaded with.

For Internet Explorer 8+:
$(window).bind(‘hashchange’, function() {
var newHash = window.location.hash;

if (newHash != originalHash) {
//get the filters from the url, will need to compare them against current filter,
// apply them if different, update the results

originalHash = newHash;

Facet search menus are generally located on the left, sometimes at the top, not usually on the right. Example sites that implement facet search menus include: Old Navy, Walmart, Amazon, Toysrus, Best Buy, Ebay and Kmart.

Leave a Reply

Your email address will not be published. Required fields are marked *