September 30, 2013

How to make your search show spellcheck suggestion

When a user is trying to search something on your website, you want to help them find what they want quickly. We are human, we make mistakes. When users make a typo, we should try to guess what they are looking for so that they don't have to type it again. Especially when more users use their smart phone/tablet to browse the web. It is much harder for them to re-type their searches.

Goal:

If the user's search didn't return anything due to spelling error, give a suggestion and list the suggestion search result.

Solution:

The default Drupal site search doesn't come with spellcheck feature. Good news is Apache Solr does! There are 2 options on setting up Solr, you can use the Apachesolr module or the Search API Solr module. I prefer Search API Solr because you can have a better control of what data to index and how the result data should be processed. So in this post I will talk about how to do it with Search API and Search API Spellcheck modules.

 

I won't go into how to setup Solr or setting up the index. I am assuming you already have a search index setup.

  1. Install and enable Search API, Search API Solr and Search API Spellcheck modules
  2. At the time of writing this post, we will need to patch the Search API Solr and spellcheck modules https://drupal.org/node/2078257
  3. Create a views search page, add the fields that you want to output.
  4. Add the "Search: Spellcheck" field in your Views Header. This will output the message “Did you mean [some suggestion]?” in the header if a suggestion is returned by Solr.
  5. Add the “Search: Fulltext search” exposed filter.
  6. (optional) If you don't have access to change your Solr settings, you will need to use the hook_search_api_solr_query_alter() function to adjust the solr settings. Checkout the Solr Wiki page to get more information on the settings below. You might want to tweak the "spellcheck.accuracy" and "spellcheck.maxCollationTries" settings to suite your requirement. The lower the accuracy, the higher chance of returning a suggestion. So you will want to find a balance.
    function MYMODULE_search_api_solr_query_alter(array &$call_args, SearchApiQueryInterface $query) { 
     $call_args['params']['spellcheck.accuracy'] = 0.7;
     $call_args['params']['spellcheck.collate'] = 'true';
     $call_args['params']['spellcheck.collateExtendedResults'] = 'true';
     $call_args['params']['spellcheck.onlyMorePopular'] = 'false';
     $call_args['params']['spellcheck.maxCollationTries'] = 1;
    }
  7. Add hook_search_api_solr_search_results_alter() function to search the suggested.
    function MYMODULE_search_api_solr_search_results_alter(array &$results, SearchApiQueryInterface $query, $response) {
     if (!count($results['results']) && !empty($response->spellcheck->suggestions->collation->collationQuery)) {
     $query->keys($response->spellcheck->suggestions->collation->collationQuery);
     $collateResults = $query->execute();
     $results['results'] = $collateResults['results'];
     $results['result count'] = $collateResults['result count'];
     }
    }

Conclusion:

And there you have it. If you are already using Search API and Solr, this is a quick way to improve user's experience on your site. Feel free to post any comments or other suggestions below.

Photo Credit: http://www.flickr.com/photos/jwyg/