-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement Top Metrics aggregation (#4594)
Implement Top Metrics aggregation
- Loading branch information
1 parent
5b074c3
commit 30b6218
Showing
8 changed files
with
255 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
src/Nest/Aggregations/Metric/TopMetrics/TopMetricsAggregate.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using System.Collections.Generic; | ||
using System.Runtime.Serialization; | ||
using Elasticsearch.Net; | ||
|
||
namespace Nest | ||
{ | ||
public class TopMetricsAggregate : MetricAggregateBase | ||
{ | ||
public IReadOnlyCollection<TopMetric> Top { get; internal set; } = EmptyReadOnly<TopMetric>.Collection; | ||
} | ||
|
||
public class TopMetric | ||
{ | ||
/// <summary> | ||
/// The sort values used in sorting the hit relative to other hits | ||
/// </summary> | ||
[DataMember(Name = "sort")] | ||
public IReadOnlyCollection<object> Sort { get; internal set; } | ||
|
||
/// <summary> | ||
/// The metrics. | ||
/// </summary> | ||
[DataMember(Name = "metrics")] | ||
public IReadOnlyDictionary<string, object> Metrics { get; internal set; } | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
src/Nest/Aggregations/Metric/TopMetrics/TopMetricsAggregation.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Runtime.Serialization; | ||
using Elasticsearch.Net.Utf8Json; | ||
|
||
namespace Nest | ||
{ | ||
[InterfaceDataContract] | ||
[ReadAs(typeof(TopMetricsAggregation))] | ||
public interface ITopMetricsAggregation : IMetricAggregation | ||
{ | ||
/// <summary> | ||
/// Metrics selects the fields of the "top" document to return. You can request a single metric or multiple metrics. | ||
/// </summary> | ||
[DataMember(Name ="metrics")] | ||
IList<ITopMetricsValue> Metrics { get; set; } | ||
|
||
/// <summary> | ||
/// Return the top few documents worth of metrics using this parameter. | ||
/// </summary> | ||
[DataMember(Name ="size")] | ||
int? Size { get; set; } | ||
|
||
/// <summary> | ||
/// The sort field in the metric request functions exactly the same as the sort field in the search request except: | ||
/// * It can’t be used on binary, flattened, ip, keyword, or text fields. | ||
/// * It only supports a single sort value so which document wins ties is not specified. | ||
/// </summary> | ||
[DataMember(Name ="sort")] | ||
IList<ISort> Sort { get; set; } | ||
} | ||
|
||
public class TopMetricsAggregation : MetricAggregationBase, ITopMetricsAggregation | ||
{ | ||
internal TopMetricsAggregation() { } | ||
|
||
public TopMetricsAggregation(string name) : base(name, null) { } | ||
|
||
/// <inheritdoc cref="ITopMetricsAggregation.Metrics" /> | ||
public IList<ITopMetricsValue> Metrics { get; set; } | ||
|
||
/// <inheritdoc cref="ITopMetricsAggregation.Size" /> | ||
public int? Size { get; set; } | ||
|
||
/// <inheritdoc cref="ITopMetricsAggregation.Sort" /> | ||
public IList<ISort> Sort { get; set; } | ||
|
||
internal override void WrapInContainer(AggregationContainer c) => c.TopMetrics = this; | ||
} | ||
|
||
public class TopMetricsAggregationDescriptor<T> | ||
: MetricAggregationDescriptorBase<TopMetricsAggregationDescriptor<T>, ITopMetricsAggregation, T>, ITopMetricsAggregation where T : class | ||
{ | ||
int? ITopMetricsAggregation.Size { get; set; } | ||
|
||
IList<ISort> ITopMetricsAggregation.Sort { get; set; } | ||
|
||
IList<ITopMetricsValue> ITopMetricsAggregation.Metrics { get; set; } | ||
|
||
/// <inheritdoc cref="ITopMetricsAggregation.Size" /> | ||
public TopMetricsAggregationDescriptor<T> Size(int? size) => Assign(size, (a, v) => | ||
a.Size = v); | ||
|
||
/// <inheritdoc cref="ITopMetricsAggregation.Sort" /> | ||
public TopMetricsAggregationDescriptor<T> Sort(Func<SortDescriptor<T>, IPromise<IList<ISort>>> sortSelector) => | ||
Assign(sortSelector, (a, v) => | ||
a.Sort = v?.Invoke(new SortDescriptor<T>())?.Value); | ||
|
||
/// <inheritdoc cref="ITopMetricsAggregation.Metrics" /> | ||
public TopMetricsAggregationDescriptor<T> Metrics(Func<TopMetricsValuesDescriptor<T>, IPromise<IList<ITopMetricsValue>>> TopMetricsValueSelector) => | ||
Assign(TopMetricsValueSelector, (a, v) => | ||
a.Metrics = v?.Invoke(new TopMetricsValuesDescriptor<T>())?.Value); | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
src/Nest/Aggregations/Metric/TopMetrics/TopMetricsValue.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq.Expressions; | ||
using System.Runtime.Serialization; | ||
using Elasticsearch.Net.Utf8Json; | ||
|
||
namespace Nest | ||
{ | ||
/// <summary> | ||
/// The configuration for a field or script that provides a value or weight | ||
/// for <see cref="TopMetricsAggregation" /> | ||
/// </summary> | ||
[InterfaceDataContract] | ||
[ReadAs(typeof(TopMetricsValue))] | ||
public interface ITopMetricsValue | ||
{ | ||
/// <summary> | ||
/// The field that values should be extracted from | ||
/// </summary> | ||
[DataMember(Name = "field")] | ||
Field Field { get; set; } | ||
} | ||
|
||
/// <inheritdoc /> | ||
public class TopMetricsValue : ITopMetricsValue | ||
{ | ||
internal TopMetricsValue() { } | ||
|
||
public TopMetricsValue(Field field) => Field = field; | ||
|
||
/// <inheritdoc /> | ||
public Field Field { get; set; } | ||
} | ||
|
||
/// <inheritdoc cref="ITopMetricsAggregation" /> | ||
public class TopMetricsValuesDescriptor<T> : DescriptorPromiseBase<TopMetricsValuesDescriptor<T>, IList<ITopMetricsValue>> | ||
where T : class | ||
{ | ||
public TopMetricsValuesDescriptor() : base(new List<ITopMetricsValue>()) { } | ||
|
||
public TopMetricsValuesDescriptor<T> Field(Field field) => AddTopMetrics(new TopMetricsValue { Field = field }); | ||
|
||
public TopMetricsValuesDescriptor<T> Field<TValue>(Expression<Func<T, TValue>> field) => | ||
AddTopMetrics(new TopMetricsValue { Field = field}); | ||
|
||
private TopMetricsValuesDescriptor<T> AddTopMetrics(ITopMetricsValue TopMetrics) => TopMetrics == null ? this : Assign(TopMetrics, (a, v) => a.Add(v)); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
tests/Tests/Aggregations/Metric/TopMetrics/TopMetricsAggregationUsageTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using Elastic.Xunit.XunitPlumbing; | ||
using FluentAssertions; | ||
using Nest; | ||
using Tests.Core.Extensions; | ||
using Tests.Core.ManagedElasticsearch.Clusters; | ||
using Tests.Domain; | ||
using Tests.Framework.EndpointTests.TestState; | ||
using static Nest.Infer; | ||
|
||
namespace Tests.Aggregations.Metric.TopMetrics | ||
{ | ||
[SkipVersion("<7.7.0", "Available in 7.7.0")] | ||
public class TopMetricsAggregationUsageTests : AggregationUsageTestBase | ||
{ | ||
public TopMetricsAggregationUsageTests(ReadOnlyCluster i, EndpointUsage usage) : base(i, usage) { } | ||
|
||
protected override object AggregationJson => new | ||
{ | ||
tm = new | ||
{ | ||
top_metrics = new | ||
{ | ||
metrics = new [] | ||
{ | ||
new | ||
{ | ||
field = "numberOfContributors" | ||
} | ||
}, | ||
size = 10, | ||
sort = new[] { new { numberOfContributors = new { order = "asc" } } } | ||
} | ||
} | ||
}; | ||
|
||
protected override Func<AggregationContainerDescriptor<Project>, IAggregationContainer> FluentAggs => a => a | ||
.TopMetrics("tm", st => st | ||
.Metrics(m => m.Field(p => p.NumberOfContributors)) | ||
.Size(10) | ||
.Sort(sort => sort | ||
.Ascending("numberOfContributors") | ||
) | ||
); | ||
|
||
protected override AggregationDictionary InitializerAggs => | ||
new TopMetricsAggregation("tm") | ||
{ | ||
Metrics = new List<ITopMetricsValue> | ||
{ | ||
new TopMetricsValue(Field<Project>(p => p.NumberOfContributors)) | ||
}, | ||
Size = 10, | ||
Sort = new List<ISort> { new FieldSort { Field = "numberOfContributors", Order = SortOrder.Ascending } } | ||
}; | ||
|
||
protected override void ExpectResponse(ISearchResponse<Project> response) | ||
{ | ||
response.ShouldBeValid(); | ||
var topMetrics = response.Aggregations.TopMetrics("tm"); | ||
topMetrics.Should().NotBeNull(); | ||
topMetrics.Top.Should().NotBeNull(); | ||
topMetrics.Top.Count.Should().BeGreaterThan(0); | ||
|
||
var tipTop = topMetrics.Top.First(); | ||
tipTop.Sort.Should().Should().NotBeNull(); | ||
tipTop.Sort.Count.Should().BeGreaterThan(0); | ||
tipTop.Metrics.Should().NotBeNull(); | ||
tipTop.Metrics.Count.Should().BeGreaterThan(0); | ||
} | ||
} | ||
} |