Skip to content

Commit

Permalink
[Backport master] Add support for rate aggregation (#5242)
Browse files Browse the repository at this point in the history
* Add support for rate aggregation (#5206)

* Add support for rate aggregation
* Add missing XML comments

* Fix namespace in master

Co-authored-by: Steve Gordon <[email protected]>
  • Loading branch information
github-actions[bot] and stevejgordon authored Jan 11, 2021
1 parent 39a774f commit 7183940
Show file tree
Hide file tree
Showing 8 changed files with 352 additions and 0 deletions.
4 changes: 4 additions & 0 deletions docs/aggregations.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ The values are typically extracted from the fields of the document (using the fi

* <<percentiles-aggregation-usage,Percentiles Aggregation Usage>>

* <<rate-aggregation-usage,Rate Aggregation Usage>>

* <<scripted-metric-aggregation-usage,Scripted Metric Aggregation Usage>>

* <<stats-aggregation-usage,Stats Aggregation Usage>>
Expand Down Expand Up @@ -100,6 +102,8 @@ include::aggregations/metric/percentile-ranks/percentile-ranks-aggregation-usage

include::aggregations/metric/percentiles/percentiles-aggregation-usage.asciidoc[]

include::aggregations/metric/rate/rate-aggregation-usage.asciidoc[]

include::aggregations/metric/scripted-metric/scripted-metric-aggregation-usage.asciidoc[]

include::aggregations/metric/stats/stats-aggregation-usage.asciidoc[]
Expand Down
94 changes: 94 additions & 0 deletions docs/aggregations/metric/rate/rate-aggregation-usage.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
:ref_current: https://www.elastic.co/guide/en/elasticsearch/reference/7.11

:github: https:/elastic/elasticsearch-net

:nuget: https://www.nuget.org/packages

////
IMPORTANT NOTE
==============
This file has been generated from https:/elastic/elasticsearch-net/tree/7.x/src/Tests/Tests/Aggregations/Metric/Rate/RateAggregationUsageTests.cs.
If you wish to submit a PR for any spelling mistakes, typos or grammatical errors for this file,
please modify the original csharp file found at the link and submit the PR with that change. Thanks!
////

[[rate-aggregation-usage]]
=== Rate Aggregation Usage

A rate metrics aggregation can be used only inside a date_histogram and calculates a rate of documents or a field in each
date_histogram bucket. The field values can be generated by a provided script or extracted from specific numeric or histogram fields in the documents.

Be sure to read the Elasticsearch documentation on {ref_current}/search-aggregations-metrics-rate-aggregation.html[Rate Aggregation].

==== Fluent DSL example

[source,csharp]
----
a => a
.DateHistogram("by_date", d => d
.Field(f => f.StartedOn)
.CalendarInterval(DateInterval.Month)
.Aggregations(a => a
.Rate("my_rate", m => m
.Field(p => p.NumberOfCommits)
.Unit(DateInterval.Month)
.Mode(RateMode.Sum)
)))
----

==== Object Initializer syntax example

[source,csharp]
----
new DateHistogramAggregation("by_date")
{
Field = Field<Project>(p => p.StartedOn),
CalendarInterval = DateInterval.Month,
Aggregations = new RateAggregation("my_rate", Field<Project>(p => p.NumberOfCommits))
{
Unit = DateInterval.Month,
Mode = RateMode.Sum
}
}
----

[source,javascript]
.Example json output
----
{
"by_date": {
"date_histogram": {
"field": "startedOn",
"calendar_interval": "month"
},
"aggs": {
"my_rate": {
"rate": {
"field": "numberOfCommits",
"unit": "month",
"mode": "sum"
}
}
}
}
}
----

==== Handling Responses

[source,csharp]
----
response.ShouldBeValid();
var dateHistogram = response.Aggregations.DateHistogram("by_date");
dateHistogram.Should().NotBeNull();
dateHistogram.Buckets.Should().NotBeNull();
dateHistogram.Buckets.Count.Should().BeGreaterThan(10);
foreach (var item in dateHistogram.Buckets)
{
var rate = item.Rate("my_rate");
rate.Should().NotBeNull();
rate.Value.Should().BeGreaterOrEqualTo(1);
}
----

2 changes: 2 additions & 0 deletions src/Nest/Aggregations/AggregateDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ public MultiBucketAggregate<RareTermsBucket<TKey>> RareTerms<TKey>(string key)
};
}

public ValueAggregate Rate(string key) => TryGet<ValueAggregate>(key);

public MultiBucketAggregate<RareTermsBucket<string>> RareTerms(string key) => RareTerms<string>(key);

public MultiBucketAggregate<RangeBucket> Range(string key) => GetMultiBucketAggregate<RangeBucket>(key);
Expand Down
11 changes: 11 additions & 0 deletions src/Nest/Aggregations/AggregationContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,9 @@ public interface IAggregationContainer
[DataMember(Name = "rare_terms")]
IRareTermsAggregation RareTerms { get; set; }

[DataMember(Name = "rate")]
IRateAggregation Rate { get; set; }

[DataMember(Name = "reverse_nested")]
IReverseNestedAggregation ReverseNested { get; set; }

Expand Down Expand Up @@ -397,6 +400,8 @@ public class AggregationContainer : IAggregationContainer

public IRareTermsAggregation RareTerms { get; set; }

public IRateAggregation Rate { get; set; }

public IReverseNestedAggregation ReverseNested { get; set; }

public ISamplerAggregation Sampler { get; set; }
Expand Down Expand Up @@ -559,6 +564,8 @@ public class AggregationContainerDescriptor<T> : DescriptorBase<AggregationConta

IRareTermsAggregation IAggregationContainer.RareTerms { get; set; }

IRateAggregation IAggregationContainer.Rate { get; set; }

IReverseNestedAggregation IAggregationContainer.ReverseNested { get; set; }

ISamplerAggregation IAggregationContainer.Sampler { get; set; }
Expand Down Expand Up @@ -733,6 +740,10 @@ Func<RareTermsAggregationDescriptor<T>, IRareTermsAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.RareTerms = d);

public AggregationContainerDescriptor<T> Rate(string name,
Func<RateAggregationDescriptor<T>, IRateAggregation> selector) =>
_SetInnerAggregation(name, selector, (a, d) => a.Rate = d);

public AggregationContainerDescriptor<T> Stats(string name,
Func<StatsAggregationDescriptor<T>, IStatsAggregation> selector
) =>
Expand Down
78 changes: 78 additions & 0 deletions src/Nest/Aggregations/Metric/Rate/RateAggregation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using System.Runtime.Serialization;
using Elasticsearch.Net;
using Nest.Utf8Json;

namespace Nest
{
[InterfaceDataContract]
[ReadAs(typeof(RateAggregation))]
public interface IRateAggregation : IMetricAggregation
{
/// <summary>
/// The <see cref="DateInterval"/> to use as the rate unit.
/// </summary>
[DataMember(Name = "unit")]
DateInterval? Unit { get; set; }

/// <summary>
/// The mode to use in the rate calculation. By default, "sum" mode is used.
/// </summary>
/// <remarks>
/// The mode may be either "sum", where the rate calculates the sum of field values, or
/// "value_count", where the rate uses the number of values in the field.
/// </remarks>
[DataMember(Name = "mode")]
RateMode? Mode { get; set; }
}

public class RateAggregation : MetricAggregationBase, IRateAggregation
{
public RateAggregation(string name) : base(name, null) { }
public RateAggregation(string name, Field field) : base(name, field) { }

internal override void WrapInContainer(AggregationContainer c) => c.Rate = this;

/// <inheritdoc cref ="IRateAggregation.Unit"/>
public DateInterval? Unit { get; set; }

/// <inheritdoc cref ="IRateAggregation.Mode"/>
public RateMode? Mode { get; set; }
}

public class RateAggregationDescriptor<T>
: MetricAggregationDescriptorBase<RateAggregationDescriptor<T>, IRateAggregation, T>, IRateAggregation
where T : class
{
DateInterval? IRateAggregation.Unit { get; set; }

RateMode? IRateAggregation.Mode { get; set; }

/// <inheritdoc cref ="IRateAggregation.Unit"/>
public RateAggregationDescriptor<T> Unit(DateInterval? dateInterval) =>
Assign(dateInterval, (a, v) => a.Unit = v);

/// <inheritdoc cref ="IRateAggregation.Mode"/>
public RateAggregationDescriptor<T> Mode(RateMode? mode) =>
Assign(mode, (a, v) => a.Mode = v);
}

[StringEnum]
public enum RateMode
{
/// <summary>
/// Rate calculates the sum of field values.
/// </summary>
[EnumMember(Value = "sum")]
Sum,

/// <summary>
/// Rate uses the number of values in the field.
/// </summary>
[EnumMember(Value = "value_count")]
ValueCount
}
}
4 changes: 4 additions & 0 deletions src/Nest/Aggregations/Visitor/AggregationVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ public interface IAggregationVisitor

void Visit(IRareTermsAggregation aggregation);

void Visit(IRateAggregation aggregation);

void Visit(ITermsAggregation aggregation);

void Visit(ISignificantTermsAggregation aggregation);
Expand Down Expand Up @@ -241,6 +243,8 @@ public virtual void Visit(IRangeAggregation aggregation) { }

public virtual void Visit(IRareTermsAggregation aggregation) { }

public virtual void Visit(IRateAggregation aggregation) { }

public virtual void Visit(INestedAggregation aggregation) { }

public virtual void Visit(INormalizeAggregation aggregation) { }
Expand Down
1 change: 1 addition & 0 deletions src/Nest/Aggregations/Visitor/AggregationWalker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ public void Walk(IAggregationContainer aggregation, IAggregationVisitor visitor)
v.Visit(d);
Accept(v, d.Aggregations);
});
AcceptAggregation(aggregation.Rate, visitor, (v, d) => v.Visit(d));
AcceptAggregation(aggregation.ReverseNested, visitor, (v, d) =>
{
v.Visit(d);
Expand Down
Loading

0 comments on commit 7183940

Please sign in to comment.