Skip to content

Commit 3312afe

Browse files
authored
Add geo-line aggregration (#5286)
* Add geo-line aggregation and initial test * Make AggregationUsageTestBase generic * Add documentation
1 parent 7b693b4 commit 3312afe

File tree

77 files changed

+463
-101
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+463
-101
lines changed

docs/aggregations.asciidoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ The values are typically extracted from the fields of the document (using the fi
4646

4747
* <<geo-centroid-aggregation-usage,Geo Centroid Aggregation Usage>>
4848

49+
* <<geo-line-aggregation-usage,Geo Line Aggregation Usage>>
50+
4951
* <<max-aggregation-usage,Max Aggregation Usage>>
5052

5153
* <<median-absolute-deviation-aggregation-usage,Median Absolute Deviation Aggregation Usage>>
@@ -92,6 +94,8 @@ include::aggregations/metric/geo-bounds/geo-bounds-aggregation-usage.asciidoc[]
9294

9395
include::aggregations/metric/geo-centroid/geo-centroid-aggregation-usage.asciidoc[]
9496

97+
include::aggregations/metric/geo-line/geo-line-aggregation-usage.asciidoc[]
98+
9599
include::aggregations/metric/max/max-aggregation-usage.asciidoc[]
96100

97101
include::aggregations/metric/median-absolute-deviation/median-absolute-deviation-aggregation-usage.asciidoc[]
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
:ref_current: https://www.elastic.co/guide/en/elasticsearch/reference/7.11
2+
3+
:github: https://github.com/elastic/elasticsearch-net
4+
5+
:nuget: https://www.nuget.org/packages
6+
7+
////
8+
IMPORTANT NOTE
9+
==============
10+
This file has been generated from https://github.com/elastic/elasticsearch-net/tree/7.x/src/Tests/Tests/Aggregations/Metric/GeoLine/GeoLineAggregationUsageTests.cs.
11+
If you wish to submit a PR for any spelling mistakes, typos or grammatical errors for this file,
12+
please modify the original csharp file found at the link and submit the PR with that change. Thanks!
13+
////
14+
15+
[[geo-line-aggregation-usage]]
16+
=== Geo Line Aggregation Usage
17+
18+
The geo_line aggregation aggregates all geo_point values within a bucket into a LineString ordered by the chosen sort field.
19+
20+
Be sure to read the Elasticsearch documentation on {ref_current}/search-aggregations-metrics-geo-line.html[Geo-Line Aggregation].
21+
22+
==== Fluent DSL example
23+
24+
[source,csharp]
25+
----
26+
a => a
27+
.GeoLine("line", d => d
28+
.Point(p => p.LocationPoint)
29+
.Sort(p => p.StartedOn)
30+
.IncludeSort()
31+
.Size(25))
32+
----
33+
34+
==== Object Initializer syntax example
35+
36+
[source,csharp]
37+
----
38+
new GeoLineAggregation("line", Field<Project>(f => f.LocationPoint), Field<Project>(f => f.StartedOn))
39+
{
40+
IncludeSort = true,
41+
Size = 25
42+
}
43+
----
44+
45+
[source,javascript]
46+
.Example json output
47+
----
48+
{
49+
"line": {
50+
"geo_line": {
51+
"point": {
52+
"field": "locationPoint"
53+
},
54+
"sort": {
55+
"field": "startedOn"
56+
},
57+
"include_sort": true,
58+
"size": 25
59+
}
60+
}
61+
}
62+
----
63+
64+
==== Handling Responses
65+
66+
[source,csharp]
67+
----
68+
response.ShouldBeValid();
69+
var geoLine = response.Aggregations.GeoLine("line");
70+
geoLine.Should().NotBeNull();
71+
geoLine.Type.Should().Be("Feature");
72+
geoLine.Geometry.Type.Should().Be("linestring");
73+
geoLine.Geometry.Coordinates.Should().NotBeEmpty();
74+
geoLine.Properties.Complete.Should().BeFalse();
75+
geoLine.Properties.SortValues.Should().NotBeEmpty();
76+
----
77+

src/Nest/Aggregations/AggregateDictionary.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ public ScriptedMetricAggregate ScriptedMetric(string key)
9494

9595
public GeoBoundsAggregate GeoBounds(string key) => TryGet<GeoBoundsAggregate>(key);
9696

97+
public GeoLineAggregate GeoLine(string key) => TryGet<GeoLineAggregate>(key);
98+
9799
public PercentilesAggregate Percentiles(string key) => TryGet<PercentilesAggregate>(key);
98100

99101
public PercentilesAggregate PercentilesBucket(string key) => TryGet<PercentilesAggregate>(key);

src/Nest/Aggregations/AggregateDictionaryFormatter.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ Dictionary<string, IAggregate> dictionary
5656
case "geo_centroid":
5757
ReadAggregate<GeoCentroidAggregate>(ref reader, formatterResolver, name, dictionary);
5858
break;
59+
case "geo_line":
60+
ReadAggregate<GeoLineAggregate>(ref reader, formatterResolver, name, dictionary);
61+
break;
5962
default:
6063
//still fall back to heuristics based parsed in case we do not know the key
6164
ParseAggregate(ref reader, formatterResolver, name, dictionary);

src/Nest/Aggregations/AggregateFormatter.cs

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ internal class AggregateFormatter : IJsonFormatter<IAggregate>
3838
{ Parser.BottomRight, 1 },
3939
};
4040

41+
private static readonly AutomataDictionary GeoLineFields = new AutomataDictionary
42+
{
43+
{ Parser.Geometry, 0 },
44+
{ Parser.Properties, 1 },
45+
};
46+
4147
private static readonly byte[] KeysField = JsonWriter.GetEncodedPropertyNameWithoutQuotation(Parser.Keys);
4248
private static readonly byte[] MetaField = JsonWriter.GetEncodedPropertyNameWithoutQuotation(Parser.Meta);
4349
private static readonly byte[] MinLengthField = JsonWriter.GetEncodedPropertyNameWithoutQuotation(Parser.MinLength);
@@ -57,6 +63,7 @@ internal class AggregateFormatter : IJsonFormatter<IAggregate>
5763
{ Parser.Fields, 10 },
5864
{ Parser.Min, 11 },
5965
{ Parser.Top, 12 },
66+
{ Parser.Type, 13 }
6067
};
6168

6269
private static readonly byte[] SumOtherDocCount = JsonWriter.GetEncodedPropertyNameWithoutQuotation(Parser.SumOtherDocCount);
@@ -174,6 +181,9 @@ private IAggregate ReadAggregate(ref JsonReader reader, IJsonFormatterResolver f
174181
case 12:
175182
aggregate = GetTopMetricsAggregate(ref reader, formatterResolver, meta);
176183
break;
184+
case 13:
185+
aggregate = GetGeoLineAggregate(ref reader, formatterResolver, meta);
186+
break;
177187
}
178188
}
179189
else
@@ -273,7 +283,7 @@ private IAggregate GetBoxplotAggregate(ref JsonReader reader, IJsonFormatterReso
273283
}
274284

275285
return boxplot;
276-
}
286+
}
277287

278288
private IAggregate GetTopMetricsAggregate(ref JsonReader reader, IJsonFormatterResolver formatterResolver, IReadOnlyDictionary<string, object> meta)
279289
{
@@ -377,6 +387,45 @@ private IAggregate GetGeoBoundsAggregate(ref JsonReader reader, IJsonFormatterRe
377387
return geoBoundsMetric;
378388
}
379389

390+
private IAggregate GetGeoLineAggregate(ref JsonReader reader, IJsonFormatterResolver formatterResolver, IReadOnlyDictionary<string, object> meta)
391+
{
392+
var geoLine = new GeoLineAggregate { Meta = meta };
393+
394+
if (reader.GetCurrentJsonToken() == JsonToken.Null)
395+
{
396+
reader.ReadNext();
397+
return geoLine;
398+
}
399+
400+
var geometryFormatter = formatterResolver.GetFormatter<LineStringGeoShape>();
401+
var propertiesFormatter = formatterResolver.GetFormatter<GeoLineProperties>();
402+
403+
geoLine.Type = reader.ReadString();
404+
reader.ReadNext();
405+
406+
for (var i = 0; i < 2; i++)
407+
{
408+
var propertyName = reader.ReadPropertyNameSegmentRaw();
409+
if (GeoLineFields.TryGetValue(propertyName, out var value))
410+
{
411+
switch (value)
412+
{
413+
case 0:
414+
geoLine.Geometry = geometryFormatter.Deserialize(ref reader, formatterResolver);
415+
reader.ReadNextBlock();
416+
break;
417+
case 1:
418+
geoLine.Properties = propertiesFormatter.Deserialize(ref reader, formatterResolver);
419+
break;
420+
}
421+
}
422+
else
423+
reader.ReadNextBlock();
424+
}
425+
426+
return geoLine;
427+
}
428+
380429
private IAggregate GetPercentilesAggregate(ref JsonReader reader, IReadOnlyDictionary<string, object> meta)
381430
{
382431
var metric = new PercentilesAggregate { Meta = meta };
@@ -944,17 +993,17 @@ private IBucket GetKeyedBucket(ref JsonReader reader, IJsonFormatterResolver for
944993
case Parser.Score:
945994
return GetSignificantTermsBucket(ref reader, formatterResolver, key, docCount);
946995
case Parser.DocCountErrorUpperBound:
947-
{
948-
docCountErrorUpperBound = reader.ReadNullableLong();
949-
token = reader.GetCurrentJsonToken();
950-
if (token == JsonToken.ValueSeparator)
951996
{
952-
reader.ReadNext(); // ,
953-
propertyName = reader.ReadPropertyName();
954-
subAggregates = GetSubAggregates(ref reader, propertyName, formatterResolver);
997+
docCountErrorUpperBound = reader.ReadNullableLong();
998+
token = reader.GetCurrentJsonToken();
999+
if (token == JsonToken.ValueSeparator)
1000+
{
1001+
reader.ReadNext(); // ,
1002+
propertyName = reader.ReadPropertyName();
1003+
subAggregates = GetSubAggregates(ref reader, propertyName, formatterResolver);
1004+
}
1005+
break;
9551006
}
956-
break;
957-
}
9581007
default:
9591008
subAggregates = GetSubAggregates(ref reader, propertyName, formatterResolver);
9601009
break;
@@ -1052,6 +1101,7 @@ private static class Parser
10521101
public const string Fields = "fields";
10531102
public const string From = "from";
10541103
public const string Top = "top";
1104+
public const string Type = "type";
10551105

10561106
public const string FromAsString = "from_as_string";
10571107
public const string Hits = "hits";
@@ -1078,6 +1128,9 @@ private static class Parser
10781128

10791129
public const string ValueAsString = "value_as_string";
10801130
public const string Values = "values";
1131+
1132+
public const string Geometry = "geometry";
1133+
public const string Properties = "properties";
10811134
}
10821135
}
10831136
}

src/Nest/Aggregations/AggregationContainer.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ public interface IAggregationContainer
162162
[DataMember(Name = "geohash_grid")]
163163
IGeoHashGridAggregation GeoHash { get; set; }
164164

165+
[DataMember(Name = "geo_line")]
166+
IGeoLineAggregation GeoLine { get; set; }
167+
165168
[DataMember(Name = "geotile_grid")]
166169
IGeoTileGridAggregation GeoTile { get; set; }
167170

@@ -355,6 +358,8 @@ public class AggregationContainer : IAggregationContainer
355358

356359
public IGeoHashGridAggregation GeoHash { get; set; }
357360

361+
public IGeoLineAggregation GeoLine { get; set; }
362+
358363
public IGeoTileGridAggregation GeoTile { get; set; }
359364

360365
public IGlobalAggregation Global { get; set; }
@@ -520,6 +525,8 @@ public class AggregationContainerDescriptor<T> : DescriptorBase<AggregationConta
520525

521526
IGeoHashGridAggregation IAggregationContainer.GeoHash { get; set; }
522527

528+
IGeoLineAggregation IAggregationContainer.GeoLine { get; set; }
529+
523530
IGeoTileGridAggregation IAggregationContainer.GeoTile { get; set; }
524531

525532
IGlobalAggregation IAggregationContainer.Global { get; set; }
@@ -662,6 +669,10 @@ Func<GeoHashGridAggregationDescriptor<T>, IGeoHashGridAggregation> selector
662669
) =>
663670
_SetInnerAggregation(name, selector, (a, d) => a.GeoHash = d);
664671

672+
public AggregationContainerDescriptor<T> GeoLine(string name,
673+
Func<GeoLineAggregationDescriptor<T>, IGeoLineAggregation> selector) =>
674+
_SetInnerAggregation(name, selector, (a, d) => a.GeoLine = d);
675+
665676
public AggregationContainerDescriptor<T> GeoTile(string name,
666677
Func<GeoTileGridAggregationDescriptor<T>, IGeoTileGridAggregation> selector
667678
) =>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using System.Collections.Generic;
6+
using System.Runtime.Serialization;
7+
8+
namespace Nest
9+
{
10+
[DataContract]
11+
public class GeoLineAggregate : MetricAggregateBase
12+
{
13+
[DataMember(Name = "type")]
14+
public string Type { get; set; }
15+
16+
[DataMember(Name = "geometry")]
17+
public LineStringGeoShape Geometry { get; set; }
18+
19+
[DataMember(Name = "properties")]
20+
public GeoLineProperties Properties { get; set; }
21+
}
22+
23+
[DataContract]
24+
public class GeoLineProperties
25+
{
26+
[DataMember(Name = "complete")]
27+
public bool Complete { get; set; }
28+
29+
[DataMember(Name = "sort_values")]
30+
public IEnumerable<double> SortValues { get; set; }
31+
}
32+
}

0 commit comments

Comments
 (0)