diff --git a/src/Nest/Search/Search/Highlighting/HighlighterType.cs b/src/Nest/Search/Search/Highlighting/HighlighterType.cs
index a835163ae85..e744c4bf4e6 100644
--- a/src/Nest/Search/Search/Highlighting/HighlighterType.cs
+++ b/src/Nest/Search/Search/Highlighting/HighlighterType.cs
@@ -12,8 +12,8 @@ public enum HighlighterType
{
///
/// Plain Highlighter.
- /// The default choice of highlighter is of type plain and uses the Lucene highlighter.
- /// It tries hard to reflect the query matching logic in terms of understanding word
+ /// The default choice of highlighter is of type plain and uses the Lucene highlighter.
+ /// It tries hard to reflect the query matching logic in terms of understanding word
/// importance and any word positioning criteria in phrase queries.
///
[EnumMember(Value = "plain")]
@@ -21,7 +21,7 @@ public enum HighlighterType
///
/// Postings Highlighter.
- /// If index_options is set to offsets in the mapping the postings highlighter
+ /// If index_options is set to offsets in the mapping the postings highlighter
/// will be used instead of the plain highlighter
///
[EnumMember(Value = "postings")]
@@ -29,10 +29,22 @@ public enum HighlighterType
///
/// Fast Vector Highlighter.
- /// If term_vector information is provided by setting term_vector to with_positions_offsets
+ /// If term_vector information is provided by setting term_vector to with_positions_offsets
/// in the mapping then the fast vector highlighter will be used instead of the plain highlighter
///
[EnumMember(Value = "fvh")]
- Fvh
+ Fvh,
+
+
+ ///
+ /// Unified Highlighter.
+ /// The unified highlighter can extract offsets from either postings, term vectors, or via re-analyzing text.
+ /// Under the hood it uses Lucene UnifiedHighlighter which picks its strategy depending on the field and the query to highlight.
+ /// Independently of the strategy this highlighter breaks the text into sentences and scores individual sentences as if
+ /// they were documents in this corpus, using the BM25 algorithm. It supports accurate phrase and multi-term
+ /// (fuzzy, prefix, regex) highlighting
+ ///
+ [EnumMember(Value = "unified")]
+ Unified
}
}
diff --git a/src/Tests/Search/Request/HighlightingUsageTests.cs b/src/Tests/Search/Request/HighlightingUsageTests.cs
index 91ff69dc40b..ab6956bdafc 100644
--- a/src/Tests/Search/Request/HighlightingUsageTests.cs
+++ b/src/Tests/Search/Request/HighlightingUsageTests.cs
@@ -23,6 +23,8 @@ public class HighlightingUsageTests : SearchUsageTestBase
{
public HighlightingUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(cluster, usage) { }
+ public string LastNameSearch { get; } = Project.Projects.First().LeadDeveloper.LastName;
+
protected override object ExpectJson => new
{
query = new
@@ -72,6 +74,26 @@ public HighlightingUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : ba
}
}
},
+ { "leadDeveloper.lastName", new JObject
+ {
+ { "type", "unified" },
+ { "pre_tags", new JArray { "" } },
+ { "post_tags", new JArray { "" } },
+ { "highlight_query", new JObject
+ {
+ { "match", new JObject
+ {
+ { "leadDeveloper.lastName", new JObject
+ {
+ { "query", LastNameSearch }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
{ "state.offsets", new JObject
{
{ "type", "postings" },
@@ -122,6 +144,17 @@ public HighlightingUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : ba
.Query("Kurt Edgardo Naomi Dariana Justice Felton")
)
),
+ fs => fs
+ .Field(p => p.LeadDeveloper.LastName)
+ .Type(HighlighterType.Unified)
+ .PreTags("")
+ .PostTags("")
+ .HighlightQuery(q => q
+ .Match(m => m
+ .Field(p => p.LeadDeveloper.LastName)
+ .Query(LastNameSearch)
+ )
+ ),
fs => fs
.Field(p => p.State.Suffix("offsets"))
.Type(HighlighterType.Postings)
@@ -175,6 +208,18 @@ public HighlightingUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : ba
}
}
},
+ { "leadDeveloper.lastName", new HighlightField
+ {
+ Type = HighlighterType.Unified,
+ PreTags = new[] { ""},
+ PostTags = new[] { ""},
+ HighlightQuery = new MatchQuery
+ {
+ Field = "leadDeveloper.lastName",
+ Query = LastNameSearch
+ }
+ }
+ },
{ "state.offsets", new HighlightField
{
Type = HighlighterType.Postings,
@@ -215,6 +260,14 @@ protected override void ExpectResponse(ISearchResponse response)
highlight.Should().Contain("");
}
}
+ else if (highlightField.Key == "leadDeveloper.lastName ")
+ {
+ foreach (var highlight in highlightField.Value.Highlights)
+ {
+ highlight.Should().Contain("");
+ highlight.Should().Contain("");
+ }
+ }
else if (highlightField.Key == "state.offsets")
{
foreach (var highlight in highlightField.Value.Highlights)