One great way to improve the search experience on a website is to suggest alternate/corrected queries if the original ones were misspelled, similar to the “Did you mean …” provided by Google. If you are interested to implement this feature, I’ve some good news and some bad news for you. The good news is, this feature can be effortlessly implmeneted using the Solr Spellcheck search component. The bad news is, unfortunately the Spellcheck search component is not supported yet by the Sitecore 7/Solr search provider.
This article will show you an easy way to extend the search provider – using extension methods – to implement the Spellcheck feature. Two main steps are needed here; configure Solr to enable the Spellcheck component, and write the extension methods.
1. Enabling the Spellchecker in Solr
Edit your solrconfig.xml and locate the following element:
<searchComponent name="spellcheck" class="solr.SpellCheckComponent">
Under the searchComponent element, configure the field that will be used for building the suggested search queries. It should look like:
<str name="field">title_t</str>
Finally, set the the “select” requestHandler to use the spellcheck search component similar to the example below:
<requestHandler name="/select" class="solr.SearchHandler"> <lst name="defaults"> <str name="echoParams">explicit</str> <int name="rows">10</int> <str name="df">text</str> <str name="terms">true</str> </lst> <arr name="last-components"> <str>spellcheck</str> </arr> </requestHandler>
2. Extending the Solr Search Context
The following code will show you how to extend the Solr search provider by leveraging the underlaying SolrNet implementation to build the spellcheck extension methods.
Getting Access to the SolrNet’s ISolrOperations
SolrNet uses Unity as IOC container. Therefore, it’s pretty straightforward to resolve its interfaces using the ServiceLocator class. The following method will retrieve the same ISolrOperations concrete implementation object used by the Search Index.
internal static ISolrOperations<Dictionary<string, object>> GetSolrOperations(this ISearchIndex searchIndex) { var solrSearchIndex = searchIndex as SolrSearchIndex; if (solrSearchIndex == null) return null; return ServiceLocator.Current.GetInstance<ISolrOperations<Dictionary<string, object>>>(solrSearchIndex.Core); }
The code above will resolve the ISolrOperations interface to retrieve an instance that uses the same Solr “Core” value defined in the “Sitecore.ContentSearch.Solr.Indexes.config” include file.
Extending the IProviderSearchContext
The next step is to write the required extension methods: BuildSpellCheckDictionary() to execute spellcheck.build=true Solr query and SpellCheck() that actually does the spellchecking. so the final code should be as follows:
public static class SearchExtensions { public static ISolrOperations<Dictionary<string, object>> GetSolrOperations(this ISearchIndex searchIndex) { var solrSearchIndex = searchIndex as SolrSearchIndex; if (solrSearchIndex == null) return null; return ServiceLocator.Current.GetInstance<ISolrOperations<Dictionary<string, object>>>(solrSearchIndex.Core); } public static void BuildSpellCheckDictionary(this IProviderSearchContext context) { var solrOperations = context.Index.GetSolrOperations(); if (solrOperations == null) return; solrOperations.BuildSpellCheckDictionary(); } public static string SpellCheck(this IProviderSearchContext context, string query) { var solrOperations = context.Index.GetSolrOperations(); if (solrOperations == null) return null; var results = solrOperations.Query(query, new QueryOptions { SpellCheck = new SpellCheckingParameters { Collate = true } , Rows = 0}); if (results != null && results.SpellChecking != null) return results.SpellChecking.Collation; return null; } }
Use the Extended Provider
Finally, this how you can use the extension methods above:
var indexName = "sitecore_web_index"; var index = ContentSearchManager.GetIndex(indexName); using (var context = index.CreateSearchContext()) { context.BuildSpellCheckDictionary(); var suggestedQuery = context.SpellCheck("welcomy to sitecori"); // suggestedQuery value is "welcome to sitecore" }
Be First to Comment