@@ -54,17 +54,6 @@ s => s
5454 .Query("Kurt Edgardo Naomi Dariana Justice Felton")
5555 )
5656 ),
57- fs => fs
58- .Field(p => p.LeadDeveloper.LastName)
59- .Type(HighlighterType.Unified)
60- .PreTags("<name>")
61- .PostTags("</name>")
62- .HighlightQuery(q => q
63- .Match(m => m
64- .Field(p => p.LeadDeveloper.LastName)
65- .Query(LastNameSearch)
66- )
67- ),
6857 fs => fs
6958 .Field(p => p.State.Suffix("offsets"))
7059 .Type(HighlighterType.Postings)
@@ -122,18 +111,6 @@ new SearchRequest<Project>
122111 }
123112 }
124113 },
125- { "leadDeveloper.lastName", new HighlightField
126- {
127- Type = HighlighterType.Unified,
128- PreTags = new[] { "<name>"},
129- PostTags = new[] { "</name>"},
130- HighlightQuery = new MatchQuery
131- {
132- Field = "leadDeveloper.lastName",
133- Query = LastNameSearch
134- }
135- }
136- },
137114 { "state.offsets", new HighlightField
138115 {
139116 Type = HighlighterType.Postings,
@@ -194,22 +171,6 @@ new SearchRequest<Project>
194171 }
195172 }
196173 },
197- "leadDeveloper.lastName": {
198- "type": "unified",
199- "pre_tags": [
200- "<name>"
201- ],
202- "post_tags": [
203- "</name>"
204- ],
205- "highlight_query": {
206- "match": {
207- "leadDeveloper.lastName": {
208- "query": "Stokes"
209- }
210- }
211- }
212- },
213174 "state.offsets": {
214175 "type": "postings",
215176 "pre_tags": [
@@ -258,20 +219,154 @@ foreach (var highlightsInEachHit in response.Hits.Select(d=>d.Highlights))
258219 highlight.Should().Contain("</name>");
259220 }
260221 }
261- else if (highlightField.Key == "leadDeveloper.lastName ")
222+ else if (highlightField.Key == "state.offsets ")
262223 {
263224 foreach (var highlight in highlightField.Value.Highlights)
264225 {
265- highlight.Should().Contain("<name >");
266- highlight.Should().Contain("</name >");
226+ highlight.Should().Contain("<state >");
227+ highlight.Should().Contain("</state >");
267228 }
268229 }
269- else if (highlightField.Key == "state.offsets")
230+ else
231+ {
232+ Assert.True(false, $"highlights contains unexpected key {highlightField.Key}");
233+ }
234+ }
235+ }
236+ ----
237+
238+ [[unified-highlighter]]
239+ [float]
240+ == Unified highlighter
241+
242+ The unified highlighter can extract offsets from either postings, term vectors, or via re-analyzing text.
243+ Under the hood it uses Lucene UnifiedHighlighter which picks its strategy depending on the
244+ field and the query to highlight.
245+
246+ [NOTE]
247+ --
248+ Unified highlighter is available only in Elasticsearch 5.3.0+
249+
250+ --
251+
252+ [WARNING]
253+ --
254+ This functionality is experimental and may be changed or removed completely in a future release.
255+ Elastic will take a best effort approach to fix any issues, but experimental features
256+ are not subject to the support SLA of official GA features.
257+
258+ --
259+
260+ === Fluent DSL Example
261+
262+ [source,csharp]
263+ ----
264+ s => s
265+ .Query(q => q
266+ .Match(m => m
267+ .Field(f => f.Name.Suffix("standard"))
268+ .Query("Upton Sons Shield Rice Rowe Roberts")
269+ )
270+ )
271+ .Highlight(h => h
272+ .Fields(
273+ fs => fs
274+ .Field(p => p.LeadDeveloper.LastName)
275+ .Type(HighlighterType.Unified)
276+ .PreTags("<name>")
277+ .PostTags("</name>")
278+ .HighlightQuery(q => q
279+ .Match(m => m
280+ .Field(p => p.LeadDeveloper.LastName)
281+ .Query(LastNameSearch)
282+ )
283+ )
284+ )
285+ )
286+ ----
287+
288+ === Object Initializer Syntax Example
289+
290+ [source,csharp]
291+ ----
292+ new SearchRequest<Project>
293+ {
294+ Query = new MatchQuery
295+ {
296+ Query = "Upton Sons Shield Rice Rowe Roberts",
297+ Field = "name.standard"
298+ },
299+ Highlight = new Highlight
300+ {
301+ Fields = new Dictionary<Field, IHighlightField>
302+ {
303+ { "leadDeveloper.lastName", new HighlightField
304+ {
305+ Type = HighlighterType.Unified,
306+ PreTags = new[] { "<name>"},
307+ PostTags = new[] { "</name>"},
308+ HighlightQuery = new MatchQuery
309+ {
310+ Field = "leadDeveloper.lastName",
311+ Query = LastNameSearch
312+ }
313+ }
314+ }
315+ }
316+ }
317+ }
318+ ----
319+
320+ [source,javascript]
321+ .Example json output
322+ ----
323+ {
324+ "query": {
325+ "match": {
326+ "name.standard": {
327+ "query": "Upton Sons Shield Rice Rowe Roberts"
328+ }
329+ }
330+ },
331+ "highlight": {
332+ "fields": {
333+ "leadDeveloper.lastName": {
334+ "type": "unified",
335+ "pre_tags": [
336+ "<name>"
337+ ],
338+ "post_tags": [
339+ "</name>"
340+ ],
341+ "highlight_query": {
342+ "match": {
343+ "leadDeveloper.lastName": {
344+ "query": "Stokes"
345+ }
346+ }
347+ }
348+ }
349+ }
350+ }
351+ }
352+ ----
353+
354+ === Handling Responses
355+
356+ [source,csharp]
357+ ----
358+ response.ShouldBeValid();
359+
360+ foreach (var highlightsInEachHit in response.Hits.Select(d => d.Highlights))
361+ {
362+ foreach (var highlightField in highlightsInEachHit)
363+ {
364+ if (highlightField.Key == "leadDeveloper.lastName")
270365 {
271366 foreach (var highlight in highlightField.Value.Highlights)
272367 {
273- highlight.Should().Contain("<state >");
274- highlight.Should().Contain("</state >");
368+ highlight.Should().Contain("<name >");
369+ highlight.Should().Contain("</name >");
275370 }
276371 }
277372 else
0 commit comments