Skip to content

Commit 48ed33e

Browse files
Add normalize aggregation (#4886) (#4896)
Relates: elastic/elasticsearch#56399 This commit adds the normalize aggregation to the high level client. Co-authored-by: Russ Cam <[email protected]>
1 parent c7b0da0 commit 48ed33e

File tree

10 files changed

+332
-0
lines changed

10 files changed

+332
-0
lines changed

docs/aggregations.asciidoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,8 @@ There are many different types of pipeline aggregation, each computing different
277277

278278
* <<moving-function-aggregation-usage,Moving Function Aggregation Usage>>
279279

280+
* <<normalize-aggregation-usage,Normalize Aggregation Usage>>
281+
280282
* <<percentiles-bucket-aggregation-usage,Percentiles Bucket Aggregation Usage>>
281283

282284
* <<serial-differencing-aggregation-usage,Serial Differencing Aggregation Usage>>
@@ -321,6 +323,8 @@ include::aggregations/pipeline/moving-average/moving-average-simple-aggregation-
321323

322324
include::aggregations/pipeline/moving-function/moving-function-aggregation-usage.asciidoc[]
323325

326+
include::aggregations/pipeline/normalize/normalize-aggregation-usage.asciidoc[]
327+
324328
include::aggregations/pipeline/percentiles-bucket/percentiles-bucket-aggregation-usage.asciidoc[]
325329

326330
include::aggregations/pipeline/serial-differencing/serial-differencing-aggregation-usage.asciidoc[]
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
:ref_current: https://www.elastic.co/guide/en/elasticsearch/reference/master
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/master/src/Tests/Tests/Aggregations/Pipeline/Normalize/NormalizeAggregationUsageTests.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+
[[normalize-aggregation-usage]]
16+
=== Normalize Aggregation Usage
17+
18+
A parent pipeline aggregation which calculates the specific normalized/rescaled value for a specific bucket value.
19+
Values that cannot be normalized, will be skipped using the skip gap policy.
20+
21+
NOTE: Valid for Elasticsearch 7.9.0+ with at least basic license level
22+
23+
==== Fluent DSL example
24+
25+
[source,csharp]
26+
----
27+
a => a
28+
.DateHistogram("projects_started_per_month", dh => dh
29+
.Field(p => p.StartedOn)
30+
.CalendarInterval(DateInterval.Month)
31+
.Aggregations(aa => aa
32+
.Sum("commits", sm => sm
33+
.Field(p => p.NumberOfCommits)
34+
)
35+
.Normalize("percent_of_commits", aaa => aaa
36+
.BucketsPath("commits")
37+
.Method(NormalizeMethod.PercentOfSum)
38+
.Format("00.00%")
39+
)
40+
)
41+
)
42+
----
43+
44+
==== Object Initializer syntax example
45+
46+
[source,csharp]
47+
----
48+
new DateHistogramAggregation("projects_started_per_month")
49+
{
50+
Field = "startedOn",
51+
CalendarInterval = DateInterval.Month,
52+
Aggregations = new SumAggregation("commits", "numberOfCommits") &&
53+
new NormalizeAggregation("percent_of_commits", "commits")
54+
{
55+
Method = NormalizeMethod.PercentOfSum,
56+
Format = "00.00%"
57+
}
58+
}
59+
----
60+
61+
[source,javascript]
62+
.Example json output
63+
----
64+
{
65+
"projects_started_per_month": {
66+
"date_histogram": {
67+
"field": "startedOn",
68+
"calendar_interval": "month"
69+
},
70+
"aggs": {
71+
"commits": {
72+
"sum": {
73+
"field": "numberOfCommits"
74+
}
75+
},
76+
"percent_of_commits": {
77+
"normalize": {
78+
"buckets_path": "commits",
79+
"method": "percent_of_sum",
80+
"format": "00.00%"
81+
}
82+
}
83+
}
84+
}
85+
}
86+
----
87+
88+
==== Handling Responses
89+
90+
[source,csharp]
91+
----
92+
response.ShouldBeValid();
93+
94+
var projectsPerMonth = response.Aggregations.DateHistogram("projects_started_per_month");
95+
projectsPerMonth.Should().NotBeNull();
96+
projectsPerMonth.Buckets.Should().NotBeNull();
97+
projectsPerMonth.Buckets.Count.Should().BeGreaterThan(0);
98+
99+
foreach (var bucket in projectsPerMonth.Buckets)
100+
{
101+
var normalize = bucket.Normalize("percent_of_commits");
102+
normalize.Value.Should().BeGreaterOrEqualTo(0);
103+
normalize.ValueAsString.Should().NotBeNullOrEmpty();
104+
}
105+
----
106+

docs/code-standards/descriptors.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ var methods = from d in YieldAllDescriptors()
211211
where !(m.Name == nameof(RankFeatureSigmoidFunctionDescriptor.Pivot) && dt == typeof(RankFeatureSigmoidFunctionDescriptor))
212212
where !(m.Name == nameof(DateHistogramGroupSourceDescriptor<object>.CalendarInterval) && dt == typeof(DateHistogramGroupSourceDescriptor<>))
213213
where !(m.Name == nameof(DateHistogramGroupSourceDescriptor<object>.FixedInterval) && dt == typeof(DateHistogramGroupSourceDescriptor<>))
214+
where !(m.Name == nameof(NormalizeAggregationDescriptor.Method) && dt == typeof(NormalizeAggregationDescriptor))
214215
215216
select new {m, d, p};
216217

src/Nest/Aggregations/AggregateDictionary.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ public FiltersAggregate Filters(string key)
122122

123123
public SingleBucketAggregate Nested(string key) => TryGet<SingleBucketAggregate>(key);
124124

125+
public ValueAggregate Normalize(string key) => TryGet<ValueAggregate>(key);
126+
125127
public SingleBucketAggregate ReverseNested(string key) => TryGet<SingleBucketAggregate>(key);
126128

127129
public SingleBucketAggregate Children(string key) => TryGet<SingleBucketAggregate>(key);

src/Nest/Aggregations/AggregationContainer.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,10 @@ public interface IAggregationContainer
202202
[DataMember(Name = "nested")]
203203
INestedAggregation Nested { get; set; }
204204

205+
/// <inheritdoc cref="INormalizeAggregation"/>
206+
[DataMember(Name = "normalize")]
207+
INormalizeAggregation Normalize { get; set; }
208+
205209
/// <inheritdoc cref="IParentAggregation"/>
206210
[DataMember(Name = "parent")]
207211
IParentAggregation Parent { get; set; }
@@ -356,6 +360,9 @@ public class AggregationContainer : IAggregationContainer
356360

357361
public INestedAggregation Nested { get; set; }
358362

363+
/// <inheritdoc cref="INormalizeAggregation"/>
364+
public INormalizeAggregation Normalize { get; set; }
365+
359366
/// <inheritdoc cref="IParentAggregation"/>
360367
public IParentAggregation Parent { get; set; }
361368

@@ -513,6 +520,8 @@ public class AggregationContainerDescriptor<T> : DescriptorBase<AggregationConta
513520

514521
INestedAggregation IAggregationContainer.Nested { get; set; }
515522

523+
INormalizeAggregation IAggregationContainer.Normalize { get; set; }
524+
516525
IParentAggregation IAggregationContainer.Parent { get; set; }
517526

518527
IPercentileRanksAggregation IAggregationContainer.PercentileRanks { get; set; }
@@ -672,6 +681,12 @@ Func<NestedAggregationDescriptor<T>, INestedAggregation> selector
672681
) =>
673682
_SetInnerAggregation(name, selector, (a, d) => a.Nested = d);
674683

684+
/// <inheritdoc cref="INormalizeAggregation"/>
685+
public AggregationContainerDescriptor<T> Normalize(string name,
686+
Func<NormalizeAggregationDescriptor, INormalizeAggregation> selector
687+
) =>
688+
_SetInnerAggregation(name, selector, (a, d) => a.Normalize = d);
689+
675690
/// <inheritdoc cref="IParentAggregation"/>
676691
public AggregationContainerDescriptor<T> Parent<TParent>(string name,
677692
Func<ParentAggregationDescriptor<T, TParent>, IParentAggregation> selector
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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.Runtime.Serialization;
6+
using Elasticsearch.Net;
7+
using Elasticsearch.Net.Utf8Json;
8+
9+
namespace Nest
10+
{
11+
/// <summary>
12+
/// A parent pipeline aggregation which calculates the specific normalized/rescaled value for a specific bucket value.
13+
/// Values that cannot be normalized, will be skipped using the skip gap policy.
14+
/// <para />
15+
/// Valid in Elasticsearch 7.9.0+ with at least basic license level.
16+
/// </summary>
17+
[InterfaceDataContract]
18+
[ReadAs(typeof(NormalizeAggregation))]
19+
public interface INormalizeAggregation : IPipelineAggregation
20+
{
21+
[DataMember(Name = "method")]
22+
NormalizeMethod Method { get; set; }
23+
}
24+
25+
/// <inheritdoc cref="INormalizeAggregation"/>
26+
public class NormalizeAggregation
27+
: PipelineAggregationBase, INormalizeAggregation
28+
{
29+
internal NormalizeAggregation() { }
30+
31+
public NormalizeAggregation(string name, SingleBucketsPath bucketsPath)
32+
: base(name, bucketsPath) { }
33+
34+
internal override void WrapInContainer(AggregationContainer c) => c.Normalize = this;
35+
36+
/// <inheritdoc cref ="INormalizeAggregation.Method"/>
37+
public NormalizeMethod Method { get; set; }
38+
}
39+
40+
/// <inheritdoc cref="INormalizeAggregation"/>
41+
public class NormalizeAggregationDescriptor
42+
: PipelineAggregationDescriptorBase<NormalizeAggregationDescriptor, INormalizeAggregation, SingleBucketsPath>
43+
, INormalizeAggregation
44+
{
45+
NormalizeMethod INormalizeAggregation.Method { get; set; }
46+
47+
/// <inheritdoc cref ="INormalizeAggregation.Method"/>
48+
public NormalizeAggregationDescriptor Method(NormalizeMethod method) =>
49+
Assign(method, (a, v) => a.Method = v);
50+
}
51+
52+
[StringEnum]
53+
public enum NormalizeMethod
54+
{
55+
/// <summary>
56+
/// rescales the data such that the minimum number is zero, and the maximum number is 1, with the rest normalized linearly in-between.
57+
/// </summary>
58+
[EnumMember(Value = "rescale_0_1")]
59+
RescaleZeroToOne,
60+
61+
/// <summary>
62+
/// rescales the data such that the minimum number is zero, and the maximum number is 1, with the rest normalized linearly in-between.
63+
/// </summary>
64+
[EnumMember(Value = "rescale_0_100")]
65+
RescaleZeroToOneHundred,
66+
67+
/// <summary>
68+
/// normalizes each value so that it represents a percentage of the total sum it attributes to.
69+
/// </summary>
70+
[EnumMember(Value = "percent_of_sum")]
71+
PercentOfSum,
72+
73+
/// <summary>
74+
/// normalizes such that each value is normalized by how much it differs from the average.
75+
/// </summary>
76+
[EnumMember(Value = "mean")]
77+
Mean,
78+
79+
/// <summary>
80+
/// normalizes such that each value represents how far it is from the mean relative to the standard deviation
81+
/// </summary>
82+
[EnumMember(Value = "zscore")]
83+
Zscore,
84+
85+
/// <summary>
86+
/// normalizes such that each value is exponentiated and relative to the sum of the exponents of the original values.
87+
/// </summary>
88+
[EnumMember(Value = "softmax")]
89+
Softmax
90+
}
91+
}

src/Nest/Aggregations/Visitor/AggregationVisitor.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ public interface IAggregationVisitor
7272

7373
void Visit(INestedAggregation aggregation);
7474

75+
void Visit(INormalizeAggregation aggregation);
76+
7577
void Visit(IParentAggregation aggregation);
7678

7779
void Visit(IReverseNestedAggregation aggregation);
@@ -233,6 +235,8 @@ public virtual void Visit(IRareTermsAggregation aggregation) { }
233235

234236
public virtual void Visit(INestedAggregation aggregation) { }
235237

238+
public virtual void Visit(INormalizeAggregation aggregation) { }
239+
236240
public virtual void Visit(IParentAggregation aggregation) { }
237241

238242
public virtual void Visit(ICardinalityAggregation aggregation) { }

src/Nest/Aggregations/Visitor/AggregationWalker.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ public void Walk(IAggregationContainer aggregation, IAggregationVisitor visitor)
122122
v.Visit(d);
123123
Accept(v, d.Aggregations);
124124
});
125+
AcceptAggregation(aggregation.Normalize, visitor, (v, d) =>
126+
{
127+
v.Visit(d);
128+
});
125129
AcceptAggregation(aggregation.Parent, visitor, (v, d) =>
126130
{
127131
v.Visit(d);

0 commit comments

Comments
 (0)