How to Highlight Search Terms using Sitecore ContentSearch with Lucene
Sitecore 7.x ContentSearch is nothing short from groundbreaking in the world of Sitecore. Although the ContentSearch API is a bit limited, it is very easily extensible, and Sitecore developers are working hard on adding more features with every update. One of the features that ContentSearch has not yet exposed is the search term highlighting with Lucene.
Lucene provides highlighting capabilities through the Lucene.Net.Search.Highlight namespace, unfortunately, in order to use this functionality, we would have to go back to the stone age of using Lucene.Net APIs, which is unacceptable in any new Sitecore solution.
Using the reflector, I was able to crawl through the entire Sitecore.ContentSearch namespace, however, did not find any trace of the Highlighter class. After working with the Sitecore support we were able to come up with a temporary solution – an extension to the IProviderSearchContext that would expose the Highlighter functionality. The solution is temporary because Sitecore has added this, as a feature request to the later releases; unfortunately, they were not able to provide any hints on which release would likely include the Highlighter. Hopefully, the feature will make it into the Sitecore.ContentSearch soon, and until then the solution below will do the job.
The ContentSearch Highlighter Source Files package includes the source files required to setup the Highlighter functionality in your solution. At a high level, we have created a new GetExtendedQueryable that is now used to get a new extended type of search results that in turn provide the Highlight() method.
To start using the ContentSearch highlighter, simply include the source files in your solution (likely some type of Utility or Framework project), and modify the namespaces to fit your architecture.
The following sample code snippet shows how to use the new extensions. The “search_index” search index contains a list of documents with “headline” and “abstract” fields that are displayed in the search results.
using (var context = ContentSearchManager.GetIndex("search_index").CreateSearchContext(SearchSecurityOptions.DisableSecurityCheck)) { var searchResult = context.GetExtendedQueryable<SearchResult>().Where(i => i.Content.Contains(searchQuery)).GetExtendedResults(); var highlights = searchResult.Highlight("headline", "abstract"); foreach (var highlightedDocument in highlights) { var document = highlightedDocument.Value.Document; var highlightsInDocument = highlightedDocument.Value.Highlights; } }
Voila! We now have a fancy search with highlighted search terms. Thanks, Sitecore Support, for helping with the setup!
Currently the highlighter is set to use the <strong /> HTML elements to highlight the terms. To modify this, please update the HighlightField method in ExtendedSearchResults.cs.
Lastly, the Lucene.Net.Search.Highlight and Lucene.Net.Index.Memory namespaces are located in the Lucene.Net.Contrib.Highlighter.dll and Lucene.Net.Contrib.Memory.dll libraries respectively that should already be in \Website\bin. Enjoy!
***UPDATE: Adjustments required for Sitecore 8
When using the source files reference above with Sitecore 8, the following error may occur “Index was outside the bounds of the array“. To get the highlighter to work with Sitecore 8 the following edits need to be made to the source files:
ExtendedLinqToLuceneIndex.cs –
private object ApplyScalarMethods<TResult, TDocument>(LuceneQuery query, object processedResults, Sitecore.ContentSearch.LuceneProvider.Search.TopDocs results)
…
private object ApplySearchMethods<TElement>(LuceneQuery query, Sitecore.ContentSearch.LuceneProvider.Search.TopDocs searchHits)
MethodExtensions.cs –
IExecutionContext exContext = !executeIndex.Parameters.ExecutionContexts.Any() ? null : executeIndex.Parameters.ExecutionContext;
Here is a Sitecore 8 Lucene Search Highlighter sample project.
Vasiliy Fomichev
August 19, 2015 at 7:47 pmHi @disqus_W53AF6HRLd:disqus, @disqus_oBPEwQsLre:disqus, @mrjasonhorne:disqus, @disqus_oaoHMfBQXL:disqus, @disqus_aUXIY3JFrJ:disqus the article has been updated to include the fix for the “out of bounds” error and tested in Sitecore 8 rev 150621. I am assuming the same fix could apply to Sitecore 7.2. Please let me know, if you run into anymore issues.
Dave
August 19, 2015 at 4:52 amI’m also getting the index outside of the bounds of the array issue….. any suggestions?
Russell Munro
August 11, 2015 at 2:55 pmOK. Thanks for replying
Thad Miller
August 11, 2015 at 5:26 amI never found a solution. I ditched Lucene entirely, and went with Solr.
Russell Munro
August 10, 2015 at 7:50 pmdid you find a fix for this Thad?
Russell Munro
August 10, 2015 at 6:45 pm“Index was outside the bounds of the array.” anyone have a solutions?
Jason
May 24, 2015 at 6:28 pmI’m having the same error as Thad: “Index was outside the bounds of the array.” issue. I have the dlls referenced as per the instructions above but still get the error. I’m using Sitecore 7.2 rev. 141226.
Jason
May 24, 2015 at 5:41 pmDid you resolve this? Im having the same problem. I have the dlls referenced as per the instructions above but still get the error. I’m using Sitecore 7.2 rev. 141226.
Jack
February 24, 2015 at 12:55 pmHave the same problem
Thad Miller
November 3, 2014 at 10:21 amI’m trying to use this on Sitecore 7.2 rev. 140526, and I’m getting an “Index was outside the bounds of the array” error on line 96 of the MethodExtensions.cs (ExtendedSearchResults). Any suggestions?
Thanks
Vasiliy Fomichev
May 23, 2014 at 8:52 am@disqus_Tk2F3GuS4O:disqus glad you were able to find the problem, please let me know if you run into anything else, or have any suggestions
Josh Jenkins
May 19, 2014 at 9:44 amNever mind me, i realized what I had done… I referenced the wrong namespaces. My bad!
Josh Jenkins
May 19, 2014 at 9:39 amLine 100 of the MethodExtensions.cs:
return new ExtendedSearchResults(results, luceneQuery.Query, analyzer, exContext);
I get:cannot convert from ‘Lucene.Net.Search.Query’ to ‘Sitecore.Data.Query.Query’ MethodExtensions.cs
Also in ExtendedSearchResult.cs on line 162
I get: cannot convert from ‘Sitecore.Data.Query.Query’ to ‘Lucene.Net.Search.Query’ ExtendedSearchResults.cs
Any ideas?