Skip to content

Commit 8adfa8a

Browse files
committed
Add phrase_limit to highlighting
- Change order from string to HighlighterOrder? - Change TagsSchema from string to HighlighterTagsSchema? - Remove BoundaryMaxSize - Change Encoder to HighlighterEncoder? - Remove encoder from highlight fields as it is only valid on the top level highlighter - Add Encoder and PhraseLimit to integration test Closes #2851
1 parent abf4b49 commit 8adfa8a

File tree

6 files changed

+114
-47
lines changed

6 files changed

+114
-47
lines changed

src/Nest/Search/Search/Highlighting/Highlight.cs

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,6 @@ public interface IHighlight
5454
[JsonProperty("fragment_offset")]
5555
int? FragmentOffset { get; set; }
5656

57-
[Obsolete("Bad mapping use BoundaryMaxScan instead")]
58-
[JsonProperty("boundary_max_size")]
59-
int? BoundaryMaxSize { get; set; }
60-
6157
/// <summary>
6258
/// Controls how far to look for boundary characters. Defaults to 20.
6359
/// </summary>
@@ -69,13 +65,13 @@ public interface IHighlight
6965
/// It can be either default (no encoding) or html (will escape html, if you use html highlighting tags).
7066
/// </summary>
7167
[JsonProperty("encoder")]
72-
string Encoder { get; set; }
68+
HighlighterEncoder? Encoder { get; set; }
7369

7470
/// <summary>
7571
/// The order in which highlighted fragments are sorted
7672
/// </summary>
7773
[JsonProperty("order")]
78-
string Order { get; set; }
74+
HighlighterOrder? Order { get; set; }
7975

8076
/// <summary>
8177
/// Use a specific "tag" schemas.
@@ -88,7 +84,7 @@ public interface IHighlight
8884
/// &lt;em class="hlt10"&gt;
8985
/// </remarks>
9086
[JsonProperty("tags_schema")]
91-
string TagsSchema { get; set; }
87+
HighlighterTagsSchema? TagsSchema { get; set; }
9288

9389
[JsonProperty("fields")]
9490
[JsonConverter(typeof(VerbatimDictionaryKeysJsonConverter<Field, IHighlightField>))]
@@ -147,21 +143,17 @@ public class Highlight : IHighlight
147143
// <inheritdoc/>
148144
public int? FragmentSize { get; set; }
149145
// <inheritdoc/>
150-
public string TagsSchema { get; set; }
146+
public HighlighterTagsSchema? TagsSchema { get; set; }
151147
// <inheritdoc/>
152148
public int? NumberOfFragments { get; set; }
153149
// <inheritdoc/>
154150
public int? FragmentOffset { get; set; }
155151
// <inheritdoc/>
156-
[Obsolete("Bad mapping use BoundaryMaxScan instead")]
157-
// <inheritdoc/>
158-
public int? BoundaryMaxSize { get; set; }
159-
// <inheritdoc/>
160152
public int? BoundaryMaxScan { get; set; }
161153
// <inheritdoc/>
162-
public string Encoder { get; set; }
154+
public HighlighterEncoder? Encoder { get; set; }
163155
// <inheritdoc/>
164-
public string Order { get; set; }
156+
public HighlighterOrder? Order { get; set; }
165157
// <inheritdoc/>
166158
public Dictionary<Field, IHighlightField> Fields { get; set; }
167159
// <inheritdoc/>
@@ -187,13 +179,12 @@ public class HighlightDescriptor<T> : DescriptorBase<HighlightDescriptor<T> ,IHi
187179
IEnumerable<string> IHighlight.PreTags { get; set; }
188180
IEnumerable<string> IHighlight.PostTags { get; set; }
189181
int? IHighlight.FragmentSize { get; set; }
190-
string IHighlight.TagsSchema { get; set; }
182+
HighlighterTagsSchema? IHighlight.TagsSchema { get; set; }
191183
int? IHighlight.NumberOfFragments { get; set; }
192184
int? IHighlight.FragmentOffset { get; set; }
193-
int? IHighlight.BoundaryMaxSize { get; set; }
194185
int? IHighlight.BoundaryMaxScan { get; set; }
195-
string IHighlight.Encoder { get; set; }
196-
string IHighlight.Order { get; set; }
186+
HighlighterEncoder? IHighlight.Encoder { get; set; }
187+
HighlighterOrder? IHighlight.Order { get; set; }
197188
Dictionary<Field, IHighlightField> IHighlight.Fields { get; set; }
198189
bool? IHighlight.RequireFieldMatch { get; set; }
199190
string IHighlight.BoundaryChars { get; set; }
@@ -215,13 +206,13 @@ public HighlightDescriptor<T> Fields(params Func<HighlightFieldDescriptor<T>, IH
215206
);
216207

217208
// <inheritdoc/>
218-
public HighlightDescriptor<T> TagsSchema(string schema = "styled") => Assign(a => a.TagsSchema = schema);
209+
public HighlightDescriptor<T> TagsSchema(HighlighterTagsSchema? schema) => Assign(a => a.TagsSchema = schema);
219210

220211
// <inheritdoc/>
221212
public HighlightDescriptor<T> PreTags(string preTags) => this.PreTags(new[] {preTags});
222213

223214
// <inheritdoc/>
224-
public HighlightDescriptor<T> PostTags(string postTags)=> this.PostTags(new[] {postTags});
215+
public HighlightDescriptor<T> PostTags(string postTags) => this.PostTags(new[] {postTags});
225216

226217
// <inheritdoc/>
227218
public HighlightDescriptor<T> PreTags(IEnumerable<string> preTags) => Assign(a => a.PreTags = preTags.ToListOrNullIfEmpty());
@@ -239,19 +230,17 @@ public HighlightDescriptor<T> Fields(params Func<HighlightFieldDescriptor<T>, IH
239230
public HighlightDescriptor<T> FragmentOffset(int fragmentOffset) => Assign(a => a.FragmentOffset = fragmentOffset);
240231

241232
// <inheritdoc/>
242-
public HighlightDescriptor<T> Encoder(string encoder) => Assign(a => a.Encoder = encoder);
233+
public HighlightDescriptor<T> Encoder(HighlighterEncoder? encoder) => Assign(a => a.Encoder = encoder);
243234

244235
// <inheritdoc/>
245-
public HighlightDescriptor<T> Order(string order) => Assign(a => a.Order = order);
236+
public HighlightDescriptor<T> Order(HighlighterOrder? order) => Assign(a => a.Order = order);
246237

247238
// <inheritdoc/>
248-
public HighlightDescriptor<T> RequireFieldMatch(bool requireFieldMatch) => Assign(a => a.RequireFieldMatch = requireFieldMatch);
239+
public HighlightDescriptor<T> RequireFieldMatch(bool requireFieldMatch = true) => Assign(a => a.RequireFieldMatch = requireFieldMatch);
249240

250241
// <inheritdoc/>
251242
public HighlightDescriptor<T> BoundaryCharacters(string boundaryCharacters) => Assign(a => a.BoundaryChars = boundaryCharacters);
252243

253-
[Obsolete("Bad mapping use BoundaryMaxScan instead")]
254-
public HighlightDescriptor<T> BoundaryMaxSize(int boundaryMaxSize) => Assign(a => a.BoundaryMaxSize = boundaryMaxSize);
255244
// <inheritdoc/>
256245
public HighlightDescriptor<T> BoundaryMaxScan(int boundaryMaxScan) => Assign(a => a.BoundaryMaxScan = boundaryMaxScan);
257246

src/Nest/Search/Search/Highlighting/HighlightField.cs

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,10 @@ public interface IHighlightField
6868
int? BoundaryMaxScan { get; set; }
6969

7070
/// <summary>
71-
/// Define how highlighted text will be encoded.
72-
/// It can be either default (no encoding) or html (will escape html, if you use html highlighting tags).
73-
/// </summary>
74-
[JsonProperty("encoder")]
75-
string Encoder { get; set; }
76-
77-
/// <summary>
78-
/// The order in which highlighted fragments are sorted
71+
/// The order in which highlighted fragments are sorted. Only valid for the unified highlighter.
7972
/// </summary>
8073
[JsonProperty("order")]
81-
string Order { get; set; }
74+
HighlighterOrder? Order { get; set; }
8275

8376
/// <summary>
8477
/// Use a specific "tag" schemas.
@@ -91,7 +84,7 @@ public interface IHighlightField
9184
/// &lt;em class="hlt10"&gt;
9285
/// </remarks>
9386
[JsonProperty("tags_schema")]
94-
string TagsSchema { get; set; }
87+
HighlighterTagsSchema? TagsSchema { get; set; }
9588

9689
/// <summary>
9790
/// Determines if only fields that hold a query match will be highlighted. Set to <c>false</c>
@@ -129,6 +122,7 @@ public interface IHighlightField
129122
/// </summary>
130123
[JsonProperty("fragmenter")]
131124
HighlighterFragmenter? Fragmenter { get; set; }
125+
132126
/// <summary>
133127
/// The type of highlighter to use. Can be a defined or custom highlighter
134128
/// </summary>
@@ -155,6 +149,15 @@ public interface IHighlightField
155149
/// </summary>
156150
[JsonProperty("highlight_query")]
157151
QueryContainer HighlightQuery { get; set; }
152+
153+
/// <summary>
154+
/// Controls the number of matching phrases in a document that are considered. Prevents the
155+
/// <see cref="HighlighterType.Fvh"/> highlighter from analyzing too many phrases and consuming too much memory.
156+
/// When using matched_fields, <see cref="PhraseLimit"/> phrases per matched field are considered. Raising the limit increases query time
157+
/// and consumes more memory. Only supported by the <see cref="HighlighterType.Fvh"/> highlighter. Defaults to 256.
158+
/// </summary>
159+
[JsonProperty("phrase_limit")]
160+
int? PhraseLimit { get; set; }
158161
}
159162

160163
public class HighlightField : IHighlightField
@@ -176,11 +179,9 @@ public class HighlightField : IHighlightField
176179
/// <inheritdoc/>
177180
public int? BoundaryMaxScan { get; set; }
178181
/// <inheritdoc/>
179-
public string Encoder { get; set; }
182+
public HighlighterOrder? Order { get; set; }
180183
/// <inheritdoc/>
181-
public string Order { get; set; }
182-
/// <inheritdoc/>
183-
public string TagsSchema { get; set; }
184+
public HighlighterTagsSchema? TagsSchema { get; set; }
184185
/// <inheritdoc/>
185186
public bool? RequireFieldMatch { get; set; }
186187
/// <inheritdoc/>
@@ -201,6 +202,8 @@ public class HighlightField : IHighlightField
201202
public Fields MatchedFields { get; set; }
202203
/// <inheritdoc/>
203204
public QueryContainer HighlightQuery { get; set; }
205+
/// <inheritdoc/>
206+
public int? PhraseLimit { get; set; }
204207
}
205208

206209
public class HighlightFieldDescriptor<T> : DescriptorBase<HighlightFieldDescriptor<T>,IHighlightField>, IHighlightField
@@ -214,9 +217,8 @@ public class HighlightFieldDescriptor<T> : DescriptorBase<HighlightFieldDescript
214217
int? IHighlightField.NumberOfFragments { get; set; }
215218
int? IHighlightField.FragmentOffset { get; set; }
216219
int? IHighlightField.BoundaryMaxScan { get; set; }
217-
string IHighlightField.Encoder { get; set; }
218-
string IHighlightField.Order { get; set; }
219-
string IHighlightField.TagsSchema { get; set; }
220+
HighlighterOrder? IHighlightField.Order { get; set; }
221+
HighlighterTagsSchema? IHighlightField.TagsSchema { get; set; }
220222
bool? IHighlightField.RequireFieldMatch { get; set; }
221223
string IHighlightField.BoundaryChars { get; set; }
222224
int? IHighlightField.MaxFragmentLength { get; set; }
@@ -227,6 +229,7 @@ public class HighlightFieldDescriptor<T> : DescriptorBase<HighlightFieldDescript
227229
bool? IHighlightField.ForceSource { get; set; }
228230
Fields IHighlightField.MatchedFields { get; set; }
229231
QueryContainer IHighlightField.HighlightQuery { get; set; }
232+
int? IHighlightField.PhraseLimit { get; set; }
230233

231234
/// <inheritdoc/>
232235
public HighlightFieldDescriptor<T> Field(Field field) => Assign(a => a.Field = field);
@@ -238,7 +241,7 @@ public class HighlightFieldDescriptor<T> : DescriptorBase<HighlightFieldDescript
238241
public HighlightFieldDescriptor<T> AllField() => this.Field("_all");
239242

240243
/// <inheritdoc/>
241-
public HighlightFieldDescriptor<T> TagsSchema(string schema = "styled") => Assign(a => a.TagsSchema = schema);
244+
public HighlightFieldDescriptor<T> TagsSchema(HighlighterTagsSchema? schema) => Assign(a => a.TagsSchema = schema);
242245

243246
/// <inheritdoc/>
244247
public HighlightFieldDescriptor<T> ForceSource(bool? force = true) => Assign(a => a.ForceSource = force);
@@ -274,10 +277,7 @@ public class HighlightFieldDescriptor<T> : DescriptorBase<HighlightFieldDescript
274277
public HighlightFieldDescriptor<T> FragmentOffset(int? fragmentOffset) => Assign(a => a.FragmentOffset = fragmentOffset);
275278

276279
/// <inheritdoc/>
277-
public HighlightFieldDescriptor<T> Encoder(string encoder) => Assign(a => a.Encoder = encoder);
278-
279-
/// <inheritdoc/>
280-
public HighlightFieldDescriptor<T> Order(string order) => Assign(a => a.Order = order);
280+
public HighlightFieldDescriptor<T> Order(HighlighterOrder? order) => Assign(a => a.Order = order);
281281

282282
/// <inheritdoc/>
283283
public HighlightFieldDescriptor<T> RequireFieldMatch(bool? requireFieldMatch = true) => Assign(a => a.RequireFieldMatch = requireFieldMatch);
@@ -307,5 +307,8 @@ public HighlightFieldDescriptor<T> HighlightQuery(Func<QueryContainerDescriptor<
307307

308308
/// <inheritdoc/>
309309
public HighlightFieldDescriptor<T> Fragmenter(HighlighterFragmenter? fragmenter) => Assign(a => a.Fragmenter = fragmenter);
310+
311+
/// <inheritdoc/>
312+
public HighlightFieldDescriptor<T> PhraseLimit(int phraseLimit) => Assign(a => a.PhraseLimit = phraseLimit);
310313
}
311314
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System.Runtime.Serialization;
2+
using Newtonsoft.Json;
3+
using Newtonsoft.Json.Converters;
4+
5+
namespace Nest
6+
{
7+
/// <summary>
8+
/// Indicates if the highlighted text should be HTML encoded
9+
/// </summary>
10+
[JsonConverter(typeof(StringEnumConverter))]
11+
public enum HighlighterEncoder
12+
{
13+
/// <summary>
14+
/// No encoding
15+
/// </summary>
16+
[EnumMember(Value = "default")]
17+
Default,
18+
/// <summary>
19+
/// Escapes HTML highlighting tags
20+
/// </summary>
21+
[EnumMember(Value = "html")]
22+
Html
23+
}
24+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System.Runtime.Serialization;
2+
using Newtonsoft.Json;
3+
using Newtonsoft.Json.Converters;
4+
5+
namespace Nest
6+
{
7+
/// <summary>
8+
/// Sorts highlighted fragments
9+
/// </summary>
10+
[JsonConverter(typeof(StringEnumConverter))]
11+
public enum HighlighterOrder
12+
{
13+
/// <summary>
14+
/// Sorts highlighted fragments by score. Only valid for the <see cref="HighlighterType.Unified"/> highligher
15+
/// </remarks>
16+
[EnumMember(Value = "score")]
17+
Score
18+
}
19+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System.Runtime.Serialization;
2+
using Newtonsoft.Json;
3+
using Newtonsoft.Json.Converters;
4+
5+
namespace Nest
6+
{
7+
/// <summary>
8+
/// Use a built-in tag schema
9+
/// </summary>
10+
[JsonConverter(typeof(StringEnumConverter))]
11+
public enum HighlighterTagsSchema
12+
{
13+
/// <summary>
14+
/// Use a specific "tag" schemas.
15+
/// </summary>
16+
/// <remarks>
17+
/// Currently a single schema called "styled" with the following pre_tags:
18+
/// &lt;em class="hlt1"&gt;, &lt;em class="hlt2"&gt;, &lt;em class="hlt3"&gt;,
19+
/// &lt;em class="hlt4"&gt;, &lt;em class="hlt5"&gt;, &lt;em class="hlt6"&gt;,
20+
/// &lt;em class="hlt7"&gt;, &lt;em class="hlt8"&gt;, &lt;em class="hlt9"&gt;,
21+
/// &lt;em class="hlt10"&gt;
22+
/// </remarks>
23+
[EnumMember(Value = "styled")]
24+
Styled
25+
}
26+
}

src/Tests/Search/Request/HighlightingUsageTests.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public HighlightingUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : ba
4242
{
4343
pre_tags = new[] { "<tag1>" },
4444
post_tags = new[] { "</tag1>" },
45+
encoder = "html",
4546
fields = new Dictionary<string, object>
4647
{
4748
{ "name.standard", new Dictionary<string, object>
@@ -57,6 +58,7 @@ public HighlightingUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : ba
5758
{ "leadDeveloper.firstName", new Dictionary<string, object>
5859
{
5960
{ "type", "fvh" },
61+
{ "phrase_limit", 10 },
6062
{ "boundary_max_scan", 50 },
6163
{ "pre_tags", new [] { "<name>" } },
6264
{ "post_tags", new [] { "</name>" } },
@@ -109,6 +111,7 @@ public HighlightingUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : ba
109111
.Highlight(h => h
110112
.PreTags("<tag1>")
111113
.PostTags("</tag1>")
114+
.Encoder(HighlighterEncoder.Html)
112115
.Fields(
113116
fs => fs
114117
.Field(p => p.Name.Suffix("standard"))
@@ -124,6 +127,7 @@ public HighlightingUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : ba
124127
.PreTags("<name>")
125128
.PostTags("</name>")
126129
.BoundaryMaxScan(50)
130+
.PhraseLimit(10)
127131
.HighlightQuery(q => q
128132
.Match(m => m
129133
.Field(p => p.LeadDeveloper.FirstName)
@@ -156,6 +160,7 @@ public HighlightingUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : ba
156160
{
157161
PreTags = new[] { "<tag1>" },
158162
PostTags = new[] { "</tag1>" },
163+
Encoder = HighlighterEncoder.Html,
159164
Fields = new Dictionary<Field, IHighlightField>
160165
{
161166
{ "name.standard", new HighlightField
@@ -171,6 +176,7 @@ public HighlightingUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : ba
171176
{ "leadDeveloper.firstName", new HighlightField
172177
{
173178
Type = "fvh",
179+
PhraseLimit = 10,
174180
BoundaryMaxScan = 50,
175181
PreTags = new[] { "<name>"},
176182
PostTags = new[] { "</name>"},

0 commit comments

Comments
 (0)