Development How To

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.

 


13 comments on “How to Highlight Search Terms using Sitecore ContentSearch with Lucene
  1. Josh Jenkins on said:

    Line 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?

  2. Josh Jenkins on said:

    Never mind me, i realized what I had done… I referenced the wrong namespaces. My bad!

  3. Thad Miller on said:

    I’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

  4. I’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.

  5. Hi @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.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.