Skip to content

Commit 9d3f09d

Browse files
committed
Add support for range queries on string fields as per documentation
See documentation at https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html fixes #1728
1 parent 203af45 commit 9d3f09d

File tree

12 files changed

+162
-37
lines changed

12 files changed

+162
-37
lines changed

paket.lock

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ NUGET
304304
xunit (2.1.0)
305305
xunit.assert (2.1.0)
306306
xunit.core (2.1.0)
307-
xunit.abstractions (2.0.0) - framework: >= net45, dnx451, dnxcore50, monoandroid, monotouch, portable-net45+win80+wp80+wpa81, xamarinios, winv4.5, wpv8.1, wpv8.0
307+
xunit.abstractions (2.0.0) - framework: >= net45, dnx451, dnxcore50, monoandroid, monotouch, portable-net45+win80+wp80+wpa81, xamarinios, winv4.5, wpv8.0
308308
xunit.assert (2.1.0)
309309
System.Collections (>= 4.0.0) - framework: dnxcore50
310310
System.Diagnostics.Debug (>= 4.0.0) - framework: dnxcore50
@@ -328,11 +328,11 @@ NUGET
328328
System.Runtime.Extensions (>= 4.0.0) - framework: dnxcore50
329329
System.Threading.Tasks (>= 4.0.0) - framework: dnxcore50
330330
xunit.abstractions (>= 2.0.0) - framework: dnxcore50
331-
xunit.extensibility.core (2.1.0) - framework: >= net45, dnx451, dnxcore50, monoandroid, monotouch, portable-net45+win80+wp80+wpa81, xamarinios, winv4.5, wpv8.1, wpv8.0
332-
xunit.extensibility.execution (2.1.0) - framework: >= net45, dnx451, dnxcore50, monoandroid, monotouch, portable-net45+win80+wp80+wpa81, xamarinios, winv4.5, wpv8.1, wpv8.0
333-
xunit.extensibility.core (2.1.0) - framework: >= net45, dnx451, dnxcore50, monoandroid, monotouch, portable-net45+win80+wp80+wpa81, xamarinios, winv4.5, wpv8.1, wpv8.0
331+
xunit.extensibility.core (2.1.0) - framework: >= net45, dnx451, dnxcore50, monoandroid, monotouch, portable-net45+win80+wp80+wpa81, xamarinios, winv4.5, wpv8.0
332+
xunit.extensibility.execution (2.1.0) - framework: >= net45, dnx451, dnxcore50, monoandroid, monotouch, portable-net45+win80+wp80+wpa81, xamarinios, winv4.5, wpv8.0
333+
xunit.extensibility.core (2.1.0) - framework: >= net45, dnx451, dnxcore50, monoandroid, monotouch, portable-net45+win80+wp80+wpa81, xamarinios, winv4.5, wpv8.0
334334
xunit.abstractions (2.0.0)
335-
xunit.extensibility.execution (2.1.0) - framework: >= net45, dnx451, dnxcore50, monoandroid, monotouch, portable-net45+win80+wp80+wpa81, xamarinios, winv4.5, wpv8.1, wpv8.0
335+
xunit.extensibility.execution (2.1.0) - framework: >= net45, dnx451, dnxcore50, monoandroid, monotouch, portable-net45+win80+wp80+wpa81, xamarinios, winv4.5, wpv8.0
336336
System.Collections (>= 4.0.0) - framework: dnxcore50
337337
System.Diagnostics.Debug (>= 4.0.0) - framework: dnxcore50
338338
System.Globalization (>= 4.0.0) - framework: dnxcore50
@@ -347,7 +347,7 @@ NUGET
347347
System.Threading (>= 4.0.0) - framework: dnxcore50
348348
System.Threading.Tasks (>= 4.0.0) - framework: dnxcore50
349349
xunit.abstractions (>= 2.0.0) - framework: dnxcore50
350-
xunit.extensibility.core (2.1.0) - framework: >= net45, dnx451, dnxcore50, monoandroid, monotouch, xamarinios, winv4.5, wpv8.1, wpv8.0
350+
xunit.extensibility.core (2.1.0) - framework: >= net45, dnx451, dnxcore50, monoandroid, monotouch, xamarinios, winv4.5, wpv8.0
351351

352352
GROUP build
353353
NUGET

src/Nest/Nest.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@
439439
<Compile Include="CommonOptions\Failures\ShardFailure.cs" />
440440
<Compile Include="QueryDsl\TermLevel\Fuzzy\FuzzyQueries.cs" />
441441
<Compile Include="QueryDsl\TermLevel\Range\DateRangeQuery .cs" />
442+
<Compile Include="QueryDsl\TermLevel\Range\TermRangeQuery.cs" />
442443
<Compile Include="QueryDsl\TermLevel\Range\RangeQueryJsonConverter.cs" />
443444
<Compile Include="QueryDsl\TermLevel\Range\NumericRangeQuery.cs" />
444445
<Compile Include="QueryDsl\VariableFields.cs" />

src/Nest/QueryDsl/Abstractions/Container/QueryContainerDescriptor.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,12 +159,18 @@ public QueryContainer Range(Func<NumericRangeQueryDescriptor<T>, INumericRangeQu
159159
/// Matches documents with fields that have terms within a certain date range.
160160
/// </summary>
161161
public QueryContainer DateRange(Func<DateRangeQueryDescriptor<T>, IDateRangeQuery> selector) =>
162-
this.Assign(selector, (query, container) => container.Range = query);
163-
164-
/// <summary>
165-
/// More like this query find documents that are “like” provided text by running it against one or more fields.
166-
/// </summary>
167-
public QueryContainer MoreLikeThis(Func<MoreLikeThisQueryDescriptor<T>, IMoreLikeThisQuery> selector) =>
162+
this.Assign(selector, (query, container) => container.Range = query);
163+
164+
/// <summary>
165+
/// Matches documents with fields that have terms within a certain term range.
166+
/// </summary>
167+
public QueryContainer TermRange(Func<TermRangeQueryDescriptor<T>, ITermRangeQuery> selector) =>
168+
this.Assign(selector, (query, container) => container.Range = query);
169+
170+
/// <summary>
171+
/// More like this query find documents that are “like” provided text by running it against one or more fields.
172+
/// </summary>
173+
public QueryContainer MoreLikeThis(Func<MoreLikeThisQueryDescriptor<T>, IMoreLikeThisQuery> selector) =>
168174
this.Assign(selector, (query, container) => container.MoreLikeThis = query);
169175

170176
/// <summary>

src/Nest/QueryDsl/Query.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,10 @@ public static QueryContainer Term<TValue>(Expression<Func<T, object>> fieldDescr
169169
new QueryContainerDescriptor<T>().Term(fieldDescriptor, value, boost);
170170

171171
public static QueryContainer Term<TValue>(string field, TValue value, double? boost = null) =>
172-
new QueryContainerDescriptor<T>().Term(field, value, boost);
172+
new QueryContainerDescriptor<T>().Term(field, value, boost);
173+
174+
public static QueryContainer TermRange(Func<TermRangeQueryDescriptor<T>, ITermRangeQuery> selector) =>
175+
new QueryContainerDescriptor<T>().TermRange(selector);
173176

174177
public static QueryContainer Terms<TValue>(Func<TermsQueryDescriptor<T, TValue>, ITermsQuery> selector) =>
175178
new QueryContainerDescriptor<T>().Terms(selector);

src/Nest/QueryDsl/TermLevel/Range/NumericRangeQuery.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ public interface INumericRangeQuery : IRangeQuery
1515

1616
[JsonProperty("lt")]
1717
double? LessThan { get; set; }
18-
1918
}
2019

2120
public class NumericRangeQuery : FieldNameQueryBase, INumericRangeQuery
@@ -56,6 +55,5 @@ public class NumericRangeQueryDescriptor<T>
5655
public NumericRangeQueryDescriptor<T> LessThan(double? to) => Assign(a => a.LessThan = to);
5756

5857
public NumericRangeQueryDescriptor<T> LessThanOrEquals(double? to) => Assign(a => a.LessThanOrEqualTo = to);
59-
6058
}
6159
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using Newtonsoft.Json;
2+
3+
namespace Nest
4+
{
5+
[JsonConverter(typeof(FieldNameQueryJsonConverter<TermRangeQuery>))]
6+
public interface ITermRangeQuery : IRangeQuery
7+
{
8+
[JsonProperty("gte")]
9+
string GreaterThanOrEqualTo { get; set; }
10+
11+
[JsonProperty("lte")]
12+
string LessThanOrEqualTo { get; set; }
13+
14+
[JsonProperty("gt")]
15+
string GreaterThan { get; set; }
16+
17+
[JsonProperty("lt")]
18+
string LessThan { get; set; }
19+
}
20+
21+
public class TermRangeQuery : FieldNameQueryBase, ITermRangeQuery
22+
{
23+
protected override bool Conditionless => IsConditionless(this);
24+
public string GreaterThanOrEqualTo { get; set; }
25+
public string LessThanOrEqualTo { get; set; }
26+
public string GreaterThan { get; set; }
27+
public string LessThan { get; set; }
28+
29+
internal override void WrapInContainer(IQueryContainer c) => c.Range = this;
30+
31+
internal static bool IsConditionless(ITermRangeQuery q)
32+
{
33+
return q.Field.IsConditionless()
34+
|| (q.GreaterThanOrEqualTo.IsNullOrEmpty()
35+
&& q.LessThanOrEqualTo.IsNullOrEmpty()
36+
&& q.GreaterThan.IsNullOrEmpty()
37+
&& q.LessThan.IsNullOrEmpty());
38+
}
39+
}
40+
41+
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
42+
public class TermRangeQueryDescriptor<T>
43+
: FieldNameQueryDescriptorBase<TermRangeQueryDescriptor<T>, ITermRangeQuery, T>
44+
, ITermRangeQuery where T : class
45+
{
46+
protected override bool Conditionless => TermRangeQuery.IsConditionless(this);
47+
string ITermRangeQuery.GreaterThanOrEqualTo { get; set; }
48+
string ITermRangeQuery.LessThanOrEqualTo { get; set; }
49+
string ITermRangeQuery.GreaterThan { get; set; }
50+
string ITermRangeQuery.LessThan { get; set; }
51+
52+
public TermRangeQueryDescriptor<T> GreaterThan(string from) => Assign(a => a.GreaterThan = from);
53+
54+
public TermRangeQueryDescriptor<T> GreaterThanOrEquals(string from) => Assign(a => a.GreaterThanOrEqualTo = from);
55+
56+
public TermRangeQueryDescriptor<T> LessThan(string to) => Assign(a => a.LessThan = to);
57+
58+
public TermRangeQueryDescriptor<T> LessThanOrEquals(string to) => Assign(a => a.LessThanOrEqualTo = to);
59+
}
60+
}

src/Nest/QueryDsl/Visitor/DslPrettyPrintVisitor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ private void Write(string queryType, Field field = null)
9292

9393
public void Visit(INumericRangeQuery query) => Write("numeric_range");
9494

95+
public void Visit(ITermRangeQuery query) => Write("term_range");
96+
9597
public virtual void Visit(IFunctionScoreQuery query) => Write("function_core");
9698

9799
public virtual void Visit(IFuzzyQuery query) => Write("fuzzy", query.Field);

src/Nest/QueryDsl/Visitor/QueryVisitor.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public interface IQueryVisitor
6262
void Visit(IExistsQuery filter);
6363
void Visit(IDateRangeQuery query);
6464
void Visit(INumericRangeQuery query);
65+
void Visit(ITermRangeQuery query);
6566
void Visit(ITemplateQuery query);
6667

6768
void Visit(ILimitQuery query);
@@ -138,6 +139,8 @@ public virtual void Visit(ISpanWithinQuery query) { }
138139
public virtual void Visit(IDateRangeQuery query) { }
139140

140141
public virtual void Visit(INumericRangeQuery query) { }
142+
143+
public virtual void Visit(ITermRangeQuery query) { }
141144
#pragma warning restore 618
142145

143146
public virtual void Visit(IFunctionScoreQuery query) { }

src/Nest/QueryDsl/Visitor/QueryWalker.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public void Walk(IQueryContainer qd, IQueryVisitor visitor)
2525
v.Visit(d);
2626
VisitQuery(d as IDateRangeQuery, visitor, (vv, dd) => v.Visit(dd));
2727
VisitQuery(d as INumericRangeQuery, visitor, (vv, dd) => v.Visit(dd));
28+
VisitQuery(d as ITermRangeQuery, visitor, (vv, dd) => v.Visit(dd));
2829
});
2930
VisitQuery(qd.GeoShape, visitor, (v, d) =>
3031
{

src/Performance/Profiling/Profiling.csproj

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,7 @@
638638
</Reference>
639639
</ItemGroup>
640640
</When>
641-
<When Condition="($(TargetFrameworkIdentifier) == 'WindowsPhoneApp') Or ($(TargetFrameworkIdentifier) == '.NETCore' And $(TargetFrameworkVersion) == 'v4.5') Or ($(TargetFrameworkIdentifier) == 'WindowsPhone' And $(TargetFrameworkVersion) == 'v8.0') Or ($(TargetFrameworkIdentifier) == 'MonoAndroid') Or ($(TargetFrameworkIdentifier) == 'MonoTouch') Or ($(TargetFrameworkIdentifier) == 'Xamarin.iOS') Or ($(TargetFrameworkProfile) == 'Profile7') Or ($(TargetFrameworkProfile) == 'Profile31') Or ($(TargetFrameworkProfile) == 'Profile32') Or ($(TargetFrameworkProfile) == 'Profile44') Or ($(TargetFrameworkProfile) == 'Profile49') Or ($(TargetFrameworkProfile) == 'Profile78') Or ($(TargetFrameworkProfile) == 'Profile84') Or ($(TargetFrameworkProfile) == 'Profile111') Or ($(TargetFrameworkProfile) == 'Profile151') Or ($(TargetFrameworkProfile) == 'Profile157') Or ($(TargetFrameworkProfile) == 'Profile259')">
641+
<When Condition="($(TargetFrameworkIdentifier) == '.NETCore' And $(TargetFrameworkVersion) == 'v4.5') Or ($(TargetFrameworkIdentifier) == 'WindowsPhone' And $(TargetFrameworkVersion) == 'v8.0') Or ($(TargetFrameworkIdentifier) == 'MonoAndroid') Or ($(TargetFrameworkIdentifier) == 'MonoTouch') Or ($(TargetFrameworkIdentifier) == 'Xamarin.iOS') Or ($(TargetFrameworkProfile) == 'Profile7') Or ($(TargetFrameworkProfile) == 'Profile31') Or ($(TargetFrameworkProfile) == 'Profile32') Or ($(TargetFrameworkProfile) == 'Profile44') Or ($(TargetFrameworkProfile) == 'Profile49') Or ($(TargetFrameworkProfile) == 'Profile78') Or ($(TargetFrameworkProfile) == 'Profile84') Or ($(TargetFrameworkProfile) == 'Profile111') Or ($(TargetFrameworkProfile) == 'Profile151') Or ($(TargetFrameworkProfile) == 'Profile157') Or ($(TargetFrameworkProfile) == 'Profile259')">
642642
<ItemGroup>
643643
<Reference Include="xunit.abstractions">
644644
<HintPath>..\..\..\packages\xunit.abstractions\lib\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.abstractions.dll</HintPath>
@@ -677,7 +677,7 @@
677677
</When>
678678
</Choose>
679679
<Choose>
680-
<When Condition="($(TargetFrameworkIdentifier) == 'WindowsPhoneApp') Or ($(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.5' Or $(TargetFrameworkVersion) == 'v4.5.1' Or $(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6' Or $(TargetFrameworkVersion) == 'v4.6.1')) Or ($(TargetFrameworkIdentifier) == '.NETCore' And $(TargetFrameworkVersion) == 'v4.5') Or ($(TargetFrameworkIdentifier) == 'WindowsPhone' And $(TargetFrameworkVersion) == 'v8.0') Or ($(TargetFrameworkIdentifier) == 'MonoAndroid') Or ($(TargetFrameworkIdentifier) == 'MonoTouch') Or ($(TargetFrameworkIdentifier) == 'Xamarin.iOS') Or ($(TargetFrameworkProfile) == 'Profile7') Or ($(TargetFrameworkProfile) == 'Profile31') Or ($(TargetFrameworkProfile) == 'Profile32') Or ($(TargetFrameworkProfile) == 'Profile44') Or ($(TargetFrameworkProfile) == 'Profile49') Or ($(TargetFrameworkProfile) == 'Profile78') Or ($(TargetFrameworkProfile) == 'Profile84') Or ($(TargetFrameworkProfile) == 'Profile111') Or ($(TargetFrameworkProfile) == 'Profile151') Or ($(TargetFrameworkProfile) == 'Profile157') Or ($(TargetFrameworkProfile) == 'Profile259')">
680+
<When Condition="($(TargetFrameworkIdentifier) == '.NETFramework' And ($(TargetFrameworkVersion) == 'v4.5' Or $(TargetFrameworkVersion) == 'v4.5.1' Or $(TargetFrameworkVersion) == 'v4.5.2' Or $(TargetFrameworkVersion) == 'v4.5.3' Or $(TargetFrameworkVersion) == 'v4.6' Or $(TargetFrameworkVersion) == 'v4.6.1')) Or ($(TargetFrameworkIdentifier) == '.NETCore' And $(TargetFrameworkVersion) == 'v4.5') Or ($(TargetFrameworkIdentifier) == 'WindowsPhone' And $(TargetFrameworkVersion) == 'v8.0') Or ($(TargetFrameworkIdentifier) == 'MonoAndroid') Or ($(TargetFrameworkIdentifier) == 'MonoTouch') Or ($(TargetFrameworkIdentifier) == 'Xamarin.iOS') Or ($(TargetFrameworkProfile) == 'Profile7') Or ($(TargetFrameworkProfile) == 'Profile31') Or ($(TargetFrameworkProfile) == 'Profile32') Or ($(TargetFrameworkProfile) == 'Profile44') Or ($(TargetFrameworkProfile) == 'Profile49') Or ($(TargetFrameworkProfile) == 'Profile78') Or ($(TargetFrameworkProfile) == 'Profile84') Or ($(TargetFrameworkProfile) == 'Profile111') Or ($(TargetFrameworkProfile) == 'Profile151') Or ($(TargetFrameworkProfile) == 'Profile157') Or ($(TargetFrameworkProfile) == 'Profile259')">
681681
<ItemGroup>
682682
<Reference Include="xunit.core">
683683
<HintPath>..\..\..\packages\xunit.extensibility.core\lib\portable-net45+win8+wp8+wpa81\xunit.core.dll</HintPath>
@@ -733,15 +733,6 @@
733733
</Reference>
734734
</ItemGroup>
735735
</When>
736-
<When Condition="$(TargetFrameworkIdentifier) == 'WindowsPhoneApp'">
737-
<ItemGroup>
738-
<Reference Include="xunit.execution.dotnet">
739-
<HintPath>..\..\..\packages\xunit.extensibility.execution\lib\wpa81\xunit.execution.dotnet.dll</HintPath>
740-
<Private>True</Private>
741-
<Paket>True</Paket>
742-
</Reference>
743-
</ItemGroup>
744-
</When>
745736
<When Condition="$(TargetFrameworkIdentifier) == 'Xamarin.iOS'">
746737
<ItemGroup>
747738
<Reference Include="xunit.execution.dotnet">

0 commit comments

Comments
 (0)