Loading...
Area: Optimizely Search & Navigation
ARCHIVED This content is retired and no longer maintained. See the latest version here.

Recommended reading 

Introduction

Highlights are fragments of the searched text with matching keywords surrounded by a HTML tag to make them stand out. Using the fluent API highlights can be requested as part of projection expressions passed to the Select method by invoking the AsHighlighted extension method on a string property.

Examples

Assuming we have indexed instances of a BlogPost class with a Title and and Content property we can search for blog posts and retrieve the Title as well as a highlight from the Content property like this:

C#
searchResult = client.Search<BlogPost>()
  .For("Bacon")
  .Select(x => new { 
    Title = x.Title, 
    Content = x.Content.AsHighlighted() 
   })
  .GetResult();

By default highlighted keywords are wrapped in em-tags. This can be overwritten by passing an instance of the HighlightSpec class to the AsHighlighted method and setting its PreTag and PostTag properties.

C#
searchResult = client.Search<BlogPost>()
  .For("Bacon")
  .Select(x => new { 
    Title = x.Title, 
    Content = x.Content.AsHighlighted(
      new HighlightSpec 
      { 
        PreTag = "<strong>", 
        PostTag = "</strong>"
      }) 
   })
  .GetResult();

By default the whole field is highlighted and retrieved. This is usually desired for shorter fields, but for longer fields we will probably want to extract one or several fragments instead. This can be achieved by setting the NumberOfFragments property on the HighlightSpec instance. The length of the fragments can also be controlled by setting the FragmentSize property. In case we do not set the FragmentSize property the server default default value, 100, will be used. Note that the FragmentSize property shouldnt be set to a value lower than 18.

As an example, we could used the below code to retrieve a single fragment with that is 200 characters long (excluding HTML tags used to wrap keywords) for the Content field.

C#
searchResult = client.Search<BlogPost>()
  .For("Bacon")
  .Select(x => new { 
    Title = x.Title, 
    Content = x.Content.AsHighlighted(
      new HighlightSpec 
      { 
        NumberOfFragments = 1, 
        FragmentSize = 200
      }) 
   })
  .GetResult();

If we set NumberOfFragments to a value greater than one and multiple fragments are passed from the server they will automatically be concatenated with a space ( ) between them. We can override this by passing in a Func<IEnumerable<string>, string> to the HighlightSpec Concatenation method.

C#
searchResult = client.Search<BlogPost>()
  .For("Bacon")
  .Select(x => new { 
    Title = x.Title, 
    Content = x.Content.AsHighlighted(
      new HighlightSpec 
      { 
        NumberOfFragments = 3, 
        Concatenation = fragments => fragments.Concatenate(" ... ")
      }) 
   })
  .GetResult();

In the above example we use an extension method that concatenates the fragments with three dots between them. We could of course do more complex things should we want to.

Sometimes there might not be any highlights for the field for which they are requested. In that case the property we project to will be an empty string. We can ensure that the value in the property is not empty by an if statement.

C#
searchResults = client.Search<BlogPost>()
  .For("Bacon")
  .Select(x => 
    !string.IsNullOrEmpty(x.Title.AsHighlighted()) 
      ? x.Title.AsHighlighted() 
      : x.Title)
  .GetResult();

Note that the if statement will be executed in memory meaning that in the above example both the highlight and the Title property will be retrieved from the server and thereby more data will be sent over the wire. That is usually not a problem, but still something to be aware of.

Do you find this information helpful? Please log in to provide feedback.

Last updated: Jun 10, 2014

Recommended reading