How to Highlight Search Terms using Sitecore ContentSearch with Lucene

Vasiliy Fomichev

In Development, How To Posted

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

Leave a Reply

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

  • Vasiliy Fomichev
    August 19, 2015 at 7:47 pm

    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.

  • Dave
    August 19, 2015 at 4:52 am

    I’m also getting the index outside of the bounds of the array issue….. any suggestions?

  • Russell Munro
    August 11, 2015 at 2:55 pm

    OK. Thanks for replying

  • Thad Miller
    August 11, 2015 at 5:26 am

    I never found a solution. I ditched Lucene entirely, and went with Solr.

  • Russell Munro
    August 10, 2015 at 7:50 pm

    did 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 pm

    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.

  • Jason
    May 24, 2015 at 5:41 pm

    Did 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 pm

    Have the same problem

  • Thad Miller
    November 3, 2014 at 10:21 am

    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

  • 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 am

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

  • Josh Jenkins
    May 19, 2014 at 9:39 am

    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?