Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for rate aggregation #5206

Merged
merged 2 commits into from
Jan 6, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -206,6 +206,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 @@ -388,6 +391,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 @@ -550,6 +555,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 @@ -724,6 +731,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
79 changes: 79 additions & 0 deletions src/Nest/Aggregations/Metric/Rate/RateAggregate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// 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 Elasticsearch.Net.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
{
internal RateAggregation() { }
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>
/// TODO
/// </summary>
[EnumMember(Value = "sum")]
Sum,

/// <summary>
/// TODO
/// </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