Highlight
Describes how to work with highlighting in Optimizely Search & Navigation.
Highlighting is used to distinguish fragments that match keywords within search results visually.
An HTML tag surrounds highlighted fragments. Using the fluent API, you can request highlighting as part of a projection expression passed to the Select method. To do so, invoke the AsHighlighted
 extension method on a string property.
Assume you indexed instances of a BlogPost
class with a Title
and Content
property. Search for BlogPost
and retrieve the Title
and a highlight from the Content
property like this.
searchResult = client.Search<BlogPost>()
.For("Bacon")
.Select(x => new {
Title = x.Title,
Content = x.Content.AsHighlighted()
})
.GetResult();
Overwrite default styling
By default, <em>
tags wrap highlighted keywords. To overwrite this styling, pass to the AsHighlighted
method an instance of the HighlightSpec
class, and set its PreTag
and PostTag
properties.
searchResult = client.Search<BlogPost>()
.For("Bacon")
.Select(x => new {
Title = x.Title,
Content = x.Content.AsHighlighted(new HighlightSpec {
PreTag = "<strong>",
PostTag = "</strong>"
})
})
.GetResult();
Control fragment number and length
Optimizely Search & Navigation, by default, retrieves and highlights the entire field, which you usually want for shorter fields. Still, you probably want to extract one or a few fragments for longer fields instead. To achieve this, set the NumberOfFragments
property on the HighlightSpec
instance.
You can also control the length of fragments by setting the FragmentSize
property. If you do not, it uses the server default value of 100.
Note
Do not set the
FragmentSize
property to a value lower than 18.
For example, the following code retrieves a single fragment that is 200 characters long (excluding HTML tags used to wrap keywords) for the Content
field.
Do not set the FragmentSize property to a value lower than 18.
Determine concatenated fragments
If you set NumberOfFragments
, multiple fragments are passed from the server to a value greater than one. It automatically concatenates fragments with a space ( ) between them. To override this, pass in a Func<IEnumerable<string>, string>
to the HighlightSpec
Concatenation
method.
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();
The previous example uses an extension method that concatenates fragments and places an ellipsis (...) between each. You can perform more complex operations.
Ensure the projected property is not empty
The projected property is an empty string if no highlights exist for the requested field. Use an if
statement to ensure that the property value is not empty.
searchResults = client.Search<BlogPost>()
.For("Bacon")
.Select(x => !string.IsNullOrEmpty(x.Title.AsHighlighted()) ?
x.Title.AsHighlighted() :
x.Title)
.GetResult();
Note
If statement is executed in memory. So, in the above example, the highlight and the Title property are retrieved from the server, which means that more data is sent over the wire. That is usually not a problem, but something to be aware of.
Highlight with typed search
Typed search provides different ways to implement the highlighting and encoding of search results.
// register a convention to remove html tags and decode any html encoded values
client.Conventions
.ForInstancesOf<BlogPost>()
.Field(x => x.Content)
.StripHtml();
// create a blog post
var blogPost = new BlogPost();
blogPost.Title = "This is a great story about apples";
blogPost.Content = "This is a great story about <strong>äpples</strong>...";
client.Index(blogPost);
// register string extensions to encode the string but preserve the highlight tags
public static class StringExtensions {
public static string EncodeAndPreserveHighlightTags(this string highlightedString) {
return highlightedString.EncodeAndPreserveHighlightTags(null, null);
}
public static string EncodeAndPreserveHighlightTags(this string highlightedString,
string preTag, string postTag) {
preTag = preTag ?? HighlightSpec.DefaultPreTag;
postTag = postTag ?? HighlightSpec.DefaultPostTag;
const string preTagMarker = "|pre|";
const string postTagMarker = "|post|";
var taggedHighlightedString = highlightedString
.Replace(preTag, preTagMarker)
.Replace(postTag, postTagMarker);
var encodedTaggedHighlightedString = HttpUtility.HtmlEncode(taggedHighlightedString);
return encodedTaggedHighlightedString
.Replace(preTagMarker, preTag)
.Replace(postTagMarker, postTag);
}
}
// issue query and request the content as encoded but with preserved highlight tags
result = client.Search<BlogPost>()
.For("Äpplen")
.Select(x => x.Content.AsHighlighted().EncodeAndPreserveHighlightTags())
.GetResult();
// the result text is encoded and highlighted
//result.First() => "This is a great story about <em>äpples</em>..."
Highlight with unified search
Unified Search enables HTML encoding by default for the Title
and Excerpt
fields. It encodes the text before adding the HTML tags that surround highlighted content. You can turn off default HTML encoding; see Unified Search.
Updated 6 months ago