Skip to content

Commit f7100fd

Browse files
Mpdreamzrusscam
authored andcommitted
Add support for ignore_unmapped on geo sorts (#3436)
Also add median as sort mode to general sorting
1 parent 1adc417 commit f7100fd

File tree

3 files changed

+101
-2
lines changed

3 files changed

+101
-2
lines changed

src/Nest/Search/Search/Sort/SortGeoDistance.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,47 @@
55

66
namespace Nest
77
{
8+
/// <summary> Allows you to sort based on a proximity to one or more <see cref="GeoLocation"/> </summary>
89
public interface IGeoDistanceSort : ISort
910
{
1011
Field Field { get; set; }
1112
IEnumerable<GeoLocation> Points { get; set; }
1213

14+
/// <summary> The unit to use when computing sort values. The default is m (meters) </summary>
1315
[JsonProperty("unit")]
1416
DistanceUnit? GeoUnit { get; set; }
1517

18+
/// <summary>
19+
/// How to compute the distance. Can either be arc (default), or plane (faster, but
20+
/// inaccurate on long distances and close to the poles).
21+
/// </summary>
1622
[JsonProperty("distance_type")]
1723
GeoDistanceType? DistanceType { get; set; }
24+
25+
/// <summary>
26+
/// Indicates if the unmapped field should be treated as a missing value. Setting it to `true` is equivalent to specifying
27+
/// an `unmapped_type` in the field sort. The default is `false` (unmapped field are causing the search to fail)
28+
/// </summary>
29+
[JsonProperty("ignore_unmapped")]
30+
bool? IgnoreUnmapped { get; set; }
1831
}
1932

33+
/// <inheritdoc cref="IGeoDistanceSort"/>
2034
public class GeoDistanceSort : SortBase, IGeoDistanceSort
2135
{
2236
protected override Field SortKey => "_geo_distance";
2337
public Field Field { get; set; }
2438
public IEnumerable<GeoLocation> Points { get; set; }
39+
/// <inheritdoc cref="IGeoDistanceSort.GeoUnit"/>
2540
public DistanceUnit? GeoUnit { get; set; }
41+
/// <inheritdoc cref="IGeoDistanceSort.DistanceType"/>
2642
public GeoDistanceType? DistanceType { get; set; }
43+
/// <inheritdoc cref="IGeoDistanceSort.IgnoreUnmapped"/>
44+
public bool? IgnoreUnmapped { get; set; }
2745

2846
}
2947

48+
/// <inheritdoc cref="IGeoDistanceSort"/>
3049
public class SortGeoDistanceDescriptor<T> : SortDescriptorBase<SortGeoDistanceDescriptor<T>, IGeoDistanceSort, T>, IGeoDistanceSort
3150
where T : class
3251
{
@@ -36,18 +55,24 @@ public class SortGeoDistanceDescriptor<T> : SortDescriptorBase<SortGeoDistanceDe
3655
IEnumerable<GeoLocation> IGeoDistanceSort.Points { get; set; }
3756
DistanceUnit? IGeoDistanceSort.GeoUnit { get; set; }
3857
GeoDistanceType? IGeoDistanceSort.DistanceType { get; set; }
58+
bool? IGeoDistanceSort.IgnoreUnmapped { get; set; }
3959

4060
public SortGeoDistanceDescriptor<T> Points(params GeoLocation[] geoLocations) => Assign(a => a.Points = geoLocations);
4161

4262
public SortGeoDistanceDescriptor<T> Points(IEnumerable<GeoLocation> geoLocations) => Assign(a => a.Points = geoLocations);
4363

64+
/// <inheritdoc cref="IGeoDistanceSort.GeoUnit"/>
4465
public SortGeoDistanceDescriptor<T> Unit(DistanceUnit? unit) => Assign(a => a.GeoUnit = unit);
4566

67+
/// <inheritdoc cref="IGeoDistanceSort.DistanceType"/>
4668
public SortGeoDistanceDescriptor<T> DistanceType(GeoDistanceType? distanceType) => Assign(a => a.DistanceType = distanceType);
4769

4870
public SortGeoDistanceDescriptor<T> Field(Field field) => Assign(a => a.Field = field);
4971

5072
public SortGeoDistanceDescriptor<T> Field(Expression<Func<T, object>> objectPath) => Assign(a => a.Field = objectPath);
5173

74+
/// <inheritdoc cref="IGeoDistanceSort.IgnoreUnmapped"/>
75+
public SortGeoDistanceDescriptor<T> IgnoreUnmapped(bool? ignoreUnmapped = true) => Assign(a => a.IgnoreUnmapped = ignoreUnmapped);
76+
5277
}
5378
}

src/Nest/Search/Search/Sort/SortMode.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,27 @@
44

55
namespace Nest
66
{
7+
/// <summary>
8+
/// Elasticsearch supports sorting by array or multi-valued fields. The mode option controls what array value is picked for
9+
/// sorting the document it belongs to.
10+
/// </summary>
711
[JsonConverter(typeof(StringEnumConverter))]
812
public enum SortMode
913
{
14+
/// <summary> Pick the lowest value. </summary>
1015
[EnumMember(Value = "min")]
1116
Min,
17+
/// <summary> Pick the highest value.</summary>
1218
[EnumMember(Value = "max")]
1319
Max,
20+
/// <summary> Use the sum of all values as sort value. Only applicable for number based array fields. </summary>
1421
[EnumMember(Value = "sum")]
1522
Sum,
23+
/// <summary> Use the average of all values as sort value. Only applicable for number based array fields. </summary>
1624
[EnumMember(Value = "avg")]
17-
Average
25+
Average,
26+
/// <summary> Use the median of all values as sort value. Only applicable for number based array fields. </summary>
27+
[EnumMember(Value = "median")]
28+
Median
1829
}
19-
}
30+
}

src/Tests/Tests/Search/Request/SortUsageTests.cs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using System.Linq.Expressions;
45
using Elastic.Xunit.XunitPlumbing;
56
using Nest;
67
using Tests.Core.ManagedElasticsearch.Clusters;
@@ -270,4 +271,66 @@ public NestedSortUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : base
270271
}
271272
};
272273
}
274+
275+
//hide
276+
[SkipVersion("<6.4.0", "IgnoreUnmapped introduced in 6.4.0 on geo distance sort")]
277+
public class GeoDistanceIgnoreUnmappedUsageTests : SearchUsageTestBase
278+
{
279+
public GeoDistanceIgnoreUnmappedUsageTests(ReadOnlyCluster cluster, EndpointUsage usage) : base(cluster, usage) { }
280+
281+
protected override object ExpectJson =>
282+
new
283+
{
284+
sort = new object[]
285+
{
286+
new
287+
{
288+
_geo_distance = new
289+
{
290+
location = new[]
291+
{
292+
new { lat = 70.0, lon = -70.0 },
293+
new { lat = -12.0, lon = 12.0 }
294+
},
295+
order = "asc",
296+
mode = "min",
297+
distance_type = "arc",
298+
ignore_unmapped = true,
299+
unit = "cm"
300+
}
301+
}
302+
}
303+
};
304+
305+
protected override Func<SearchDescriptor<Project>, ISearchRequest> Fluent => s => s
306+
.Sort(ss => ss
307+
.GeoDistance(g => g
308+
.Field(p => p.Location)
309+
.IgnoreUnmapped()
310+
.DistanceType(GeoDistanceType.Arc)
311+
.Order(SortOrder.Ascending)
312+
.Unit(DistanceUnit.Centimeters)
313+
.Mode(SortMode.Min)
314+
.Points(new GeoLocation(70, -70), new GeoLocation(-12, 12))
315+
)
316+
);
317+
318+
protected override SearchRequest<Project> Initializer =>
319+
new SearchRequest<Project>
320+
{
321+
Sort = new List<ISort>
322+
{
323+
new GeoDistanceSort
324+
{
325+
Field = "location",
326+
IgnoreUnmapped = true,
327+
Order = SortOrder.Ascending,
328+
DistanceType = GeoDistanceType.Arc,
329+
GeoUnit = DistanceUnit.Centimeters,
330+
Mode = SortMode.Min,
331+
Points = new[] {new GeoLocation(70, -70), new GeoLocation(-12, 12)}
332+
},
333+
}
334+
};
335+
}
273336
}

0 commit comments

Comments
 (0)