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.