Skip to content

Commit bd6b0a6

Browse files
committed
Merge pull request #1076 from elasticsearch/feature/highlight-query
Feature/highlight query
2 parents fea53ca + ad619f0 commit bd6b0a6

File tree

6 files changed

+125
-3
lines changed

6 files changed

+125
-3
lines changed

src/Nest/DSL/Search/HighlightDescriptor.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ public interface IHighlightRequest
4646

4747
[JsonProperty("boundary_chars")]
4848
string BoundaryChars { get; set; }
49+
50+
[JsonProperty("highlight_query")]
51+
IQueryContainer HighlightQuery { get; set; }
4952
}
5053

5154
public class HighlightRequest : IHighlightRequest
@@ -62,6 +65,7 @@ public class HighlightRequest : IHighlightRequest
6265
public Dictionary<PropertyPathMarker, IHighlightField> Fields { get; set; }
6366
public bool? RequireFieldMatch { get; set; }
6467
public string BoundaryChars { get; set; }
68+
public IQueryContainer HighlightQuery { get; set; }
6569
}
6670

6771
public class HighlightDescriptor<T> : IHighlightRequest
@@ -93,6 +97,8 @@ public class HighlightDescriptor<T> : IHighlightRequest
9397

9498
string IHighlightRequest.BoundaryChars { get; set; }
9599

100+
IQueryContainer IHighlightRequest.HighlightQuery { get; set; }
101+
96102
public HighlightDescriptor<T> OnFields(params Action<HighlightFieldDescriptor<T>>[] fieldHighlighters)
97103
{
98104
fieldHighlighters.ThrowIfEmpty("fieldHighlighters");
@@ -182,5 +188,10 @@ public HighlightDescriptor<T> BoundaryMaxSize(int boundaryMaxSize)
182188
Self.BoundaryMaxSize = boundaryMaxSize;
183189
return this;
184190
}
191+
public HighlightDescriptor<T> HighlightQuery(Func<QueryDescriptor<T>, QueryContainer> query)
192+
{
193+
Self.HighlightQuery = query(new QueryDescriptor<T>());
194+
return this;
195+
}
185196
}
186197
}

src/Nest/DSL/Search/HighlightFieldDescriptor.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ public interface IHighlightField
5454

5555
[JsonProperty("force_source")]
5656
bool? ForceSource { get; set; }
57+
58+
[JsonProperty("matched_fields")]
59+
IEnumerable<PropertyPathMarker> MatchedFields { get; set; }
5760
}
5861

5962
public class HighlightField : IHighlightField
@@ -73,6 +76,7 @@ public class HighlightField : IHighlightField
7376
public string BoundaryChars { get; set; }
7477
public string Type { get; set; }
7578
public bool? ForceSource { get; set; }
79+
public IEnumerable<PropertyPathMarker> MatchedFields { get; set; }
7680
}
7781

7882
public class HighlightFieldDescriptor<T> : IHighlightField where T : class
@@ -108,6 +112,8 @@ public class HighlightFieldDescriptor<T> : IHighlightField where T : class
108112
string IHighlightField.Type { get; set; }
109113

110114
bool? IHighlightField.ForceSource { get; set; }
115+
116+
IEnumerable<PropertyPathMarker> IHighlightField.MatchedFields { get; set; }
111117

112118
public HighlightFieldDescriptor<T> OnField(string field)
113119
{
@@ -138,6 +144,11 @@ public HighlightFieldDescriptor<T> Type(string type)
138144
Self.Type = type;
139145
return this;
140146
}
147+
public HighlightFieldDescriptor<T> Type(HighlighterType type)
148+
{
149+
Self.Type = type.GetStringValue();
150+
return this;
151+
}
141152
public HighlightFieldDescriptor<T> PreTags(string preTags)
142153
{
143154
Self.PreTags = new[] { preTags };
@@ -203,5 +214,15 @@ public HighlightFieldDescriptor<T> BoundaryMaxSize(int boundaryMaxSize)
203214
Self.BoundaryMaxSize = boundaryMaxSize;
204215
return this;
205216
}
217+
public HighlightFieldDescriptor<T> MatchedFields(IEnumerable<string> fields)
218+
{
219+
Self.MatchedFields = fields.Select(f => (PropertyPathMarker)f);
220+
return this;
221+
}
222+
public HighlightFieldDescriptor<T> MatchedFields(params Expression<Func<T, object>>[] objectPaths)
223+
{
224+
Self.MatchedFields = objectPaths.Select(f => (PropertyPathMarker)f);
225+
return this;
226+
}
206227
}
207228
}

src/Nest/Enums/HighlighterType.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Runtime.Serialization;
5+
using System.Text;
6+
7+
namespace Nest
8+
{
9+
public enum HighlighterType
10+
{
11+
[EnumMember(Value = "plain")]
12+
Plain,
13+
[EnumMember(Value = "postings")]
14+
Postings,
15+
[EnumMember(Value = "fvh")]
16+
Fvh
17+
}
18+
}

src/Nest/Nest.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@
369369
<Compile Include="Enums\FieldDataLoading.cs" />
370370
<Compile Include="Enums\FieldDataNonStringFormat.cs" />
371371
<Compile Include="Enums\FieldDataStringFormat.cs" />
372+
<Compile Include="Enums\HighlighterType.cs" />
372373
<Compile Include="Enums\NormsLoading.cs" />
373374
<Compile Include="Enums\RoutingAllocationEnableOption.cs" />
374375
<Compile Include="Enums\ScriptLang.cs" />

src/Tests/Nest.Tests.Integration/Search/HighlightTests.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,53 @@ public void TestHighlightNoNullRef()
8080
Assert.GreaterOrEqual(result.Total, 1);
8181
Assert.AreEqual(result.Highlights.Count(), 0);
8282
}
83+
84+
[Test]
85+
public void TestHighlightQuery()
86+
{
87+
var result = this.Client.Search<ElasticsearchProject>(s => s
88+
.From(0)
89+
.Size(10)
90+
.Query(q => q
91+
.QueryString(qs => qs
92+
.Query("elasticsearch.pm")
93+
)
94+
)
95+
.Highlight(h => h
96+
.HighlightQuery(hq => hq
97+
.Bool(b => b
98+
.Must(m => m
99+
.Match(mm => mm
100+
.OnField(p => p.Name)
101+
.Query("elasticsearch.pm")
102+
)
103+
)
104+
.Should(sh => sh
105+
.MatchPhrase(mp => mp
106+
.OnField(p => p.Name)
107+
.Slop(1)
108+
.Boost(10)
109+
)
110+
)
111+
.MinimumShouldMatch(0)
112+
)
113+
)
114+
.PreTags("<b>")
115+
.PostTags("</b>")
116+
.OnFields(
117+
f => f
118+
.OnField(e => e.Name)
119+
.PreTags("<em>")
120+
.PostTags("</em>")
121+
)
122+
)
123+
);
124+
125+
Assert.IsTrue(result.IsValid);
126+
Assert.DoesNotThrow(() => result.Highlights.Count());
127+
Assert.IsNotNull(result.Highlights);
128+
Assert.GreaterOrEqual(result.Total, 2);
129+
Assert.AreEqual(result.Highlights.Count(), 2);
130+
}
83131
}
84132
}

src/Tests/Nest.Tests.Unit/Search/Highlight/HighlightTests.cs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ public void TestHighlight()
1313
.From(0)
1414
.Size(10)
1515
.Highlight(h => h
16+
.HighlightQuery(hq => hq
17+
.Match(m => m
18+
.OnField(p => p.Name)
19+
.Query("nest")
20+
)
21+
)
1622
.BoundaryCharacters(".,!? \t\n")
1723
.BoundaryMaxSize(20)
1824
.Encoder("html")
@@ -26,9 +32,14 @@ public void TestHighlight()
2632
.OnFields(
2733
f => f
2834
.OnAll()
29-
.NoMatchSize(200)
35+
.NoMatchSize(200)
3036
.PreTags("<em>")
3137
.PostTags("</em>")
38+
.Type(HighlighterType.Plain),
39+
f => f
40+
.OnField(p => p.Name)
41+
.Type(HighlighterType.Postings)
42+
.MatchedFields(mf => mf.Country, mf => mf.Content)
3243
)
3344
);
3445
var json = TestElasticClient.Serialize(s);
@@ -48,11 +59,23 @@ public void TestHighlight()
4859
_all: {
4960
pre_tags: [""<em>""],
5061
post_tags: [""</em>""],
51-
no_match_size: 200
62+
no_match_size: 200,
63+
type: ""plain""
64+
},
65+
name: {
66+
type: ""postings"",
67+
matched_fields: [ ""country"", ""content"" ]
5268
}
5369
},
5470
require_field_match: true,
55-
boundary_chars: "".,!? \t\n""
71+
boundary_chars: "".,!? \t\n"",
72+
highlight_query: {
73+
match: {
74+
name: {
75+
query: ""nest""
76+
}
77+
}
78+
}
5679
}
5780
}";
5881
Assert.True(json.JsonEquals(expected), json);

0 commit comments

Comments
 (0)