From 9e6778784ad9782c2c3d56d30dcef1d2c3555cd5 Mon Sep 17 00:00:00 2001 From: Steve Gordon Date: Thu, 28 Jul 2022 13:17:11 +0100 Subject: [PATCH] Fix GetTerms and sub-aggregations (#6627) --- .../Types/Aggregations/AggregateDictionary.cs | 59 +++++++++++-------- .../Types/Aggregations/TermsBucket.cs | 12 ++-- .../Metric/AverageAggregationUsageTests.cs | 2 +- .../Tests/AsyncSearch/AsyncSearchApiTests.cs | 2 +- .../TermsAggregateDeserializationTests.cs | 19 +++--- 5 files changed, 53 insertions(+), 41 deletions(-) diff --git a/src/Elastic.Clients.Elasticsearch/Types/Aggregations/AggregateDictionary.cs b/src/Elastic.Clients.Elasticsearch/Types/Aggregations/AggregateDictionary.cs index aa10d15f500..ed21392c4ea 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Aggregations/AggregateDictionary.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Aggregations/AggregateDictionary.cs @@ -14,24 +14,35 @@ public partial class AggregateDictionary public bool IsEmptyTerms(string key) => !BackingDictionary.TryGetValue(key, out var agg) || agg is EmptyTermsAggregate; - public bool TryGetStringTerms(string key, out StringTermsAggregate? aggregate) - { - aggregate = null; - - if (BackingDictionary.TryGetValue(key, out var agg) && agg is StringTermsAggregate stringTermsAgg) - { - aggregate = stringTermsAgg; - return true; - } - - return false; - } - - public AvgAggregate? Average(string key) => TryGet(key); - - public TermsAggregate Terms(string key) => Terms(key); - - public TermsAggregate Terms(string key) + // This should be autogenerated if we want to include this. + //public bool TryGetStringTerms(string key, out StringTermsAggregate? aggregate) + //{ + // aggregate = null; + + // if (BackingDictionary.TryGetValue(key, out var agg) && agg is StringTermsAggregate stringTermsAgg) + // { + // aggregate = stringTermsAgg; + // return true; + // } + + // return false; + //} + + public AvgAggregate? GetAverage(string key) => TryGet(key); + + /// + /// WARNING: EXPERIMENTAL API + /// This API provides simplified access to terms aggregations. + /// + /// Experimental APIs are subject to changes or removal and should be used with caution. + public TermsAggregate GetTerms(string key) => GetTerms(key); + + /// + /// WARNING: EXPERIMENTAL API + /// This API provides simplified access to terms aggregations. + /// + /// Experimental APIs are subject to changes or removal and should be used with caution. + public TermsAggregate GetTerms(string key) { if (!BackingDictionary.TryGetValue(key, out var agg)) { @@ -59,12 +70,12 @@ public TermsAggregate Terms(string key) { var key = item.Key; var value = item.Value; - dict.Add(key, new TermsBucket { DocCount = value.DocCount, DocCountError = value.DocCountError, Key = GetKeyFromBucketKey(value.Key), KeyAsString = value.Key }); + dict.Add(key, new TermsBucket(value.BackingDictionary) { DocCount = value.DocCount, DocCountError = value.DocCountError, Key = GetKeyFromBucketKey(value.Key), KeyAsString = value.Key }); } buckets = new(dict); }, a => { - buckets = new(a.Select(b => new TermsBucket { DocCount = b.DocCount, DocCountError = b.DocCountError, Key = GetKeyFromBucketKey(b.Key), KeyAsString = b.Key }).ToReadOnlyCollection()); + buckets = new(a.Select(b => new TermsBucket(b.BackingDictionary) { DocCount = b.DocCount, DocCountError = b.DocCountError, Key = GetKeyFromBucketKey(b.Key), KeyAsString = b.Key }).ToReadOnlyCollection()); }); return new TermsAggregate @@ -83,12 +94,12 @@ public TermsAggregate Terms(string key) { var key = item.Key; var value = item.Value; - dict.Add(key, new TermsBucket { DocCount = value.DocCount, DocCountError = value.DocCountError, Key = GetKeyFromBucketKey(value.Key), KeyAsString = value.KeyAsString }); + dict.Add(key, new TermsBucket(value.BackingDictionary) { DocCount = value.DocCount, DocCountError = value.DocCountError, Key = GetKeyFromBucketKey(value.Key), KeyAsString = value.KeyAsString }); } buckets = new(dict); }, a => { - buckets = new(a.Select(b => new TermsBucket { DocCount = b.DocCount, DocCountError = b.DocCountError, Key = GetKeyFromBucketKey(b.Key), KeyAsString = b.KeyAsString }).ToReadOnlyCollection()); + buckets = new(a.Select(b => new TermsBucket(b.BackingDictionary) { DocCount = b.DocCount, DocCountError = b.DocCountError, Key = GetKeyFromBucketKey(b.Key), KeyAsString = b.KeyAsString }).ToReadOnlyCollection()); }); return new TermsAggregate @@ -107,12 +118,12 @@ public TermsAggregate Terms(string key) { var key = item.Key; var value = item.Value; - dict.Add(key, new TermsBucket { DocCount = value.DocCount, DocCountError = value.DocCountError, Key = GetKeyFromBucketKey(value.Key), KeyAsString = value.KeyAsString }); + dict.Add(key, new TermsBucket(value.BackingDictionary) { DocCount = value.DocCount, DocCountError = value.DocCountError, Key = GetKeyFromBucketKey(value.Key), KeyAsString = value.KeyAsString }); } buckets = new(dict); }, a => { - buckets = new(a.Select(b => new TermsBucket { DocCount = b.DocCount, DocCountError = b.DocCountError, Key = GetKeyFromBucketKey(b.Key), KeyAsString = b.KeyAsString }).ToReadOnlyCollection()); + buckets = new(a.Select(b => new TermsBucket(b.BackingDictionary) { DocCount = b.DocCount, DocCountError = b.DocCountError, Key = GetKeyFromBucketKey(b.Key), KeyAsString = b.KeyAsString }).ToReadOnlyCollection()); }); return new TermsAggregate diff --git a/src/Elastic.Clients.Elasticsearch/Types/Aggregations/TermsBucket.cs b/src/Elastic.Clients.Elasticsearch/Types/Aggregations/TermsBucket.cs index 3d6d063bf6a..424b42cf2dc 100644 --- a/src/Elastic.Clients.Elasticsearch/Types/Aggregations/TermsBucket.cs +++ b/src/Elastic.Clients.Elasticsearch/Types/Aggregations/TermsBucket.cs @@ -2,23 +2,25 @@ // 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.Collections.Generic; using System.Text.Json.Serialization; namespace Elastic.Clients.Elasticsearch.Aggregations; -public sealed class TermsBucket +public sealed class TermsBucket : AggregateDictionary { + public TermsBucket(IReadOnlyDictionary backingDictionary) : base(backingDictionary) + { + } + public TKey Key { get; init; } + public string? KeyAsString { get; init; } [JsonInclude] [JsonPropertyName("doc_count_error")] public long? DocCountError { get; init; } - [JsonInclude] - [JsonPropertyName("aggregations")] - public Elastic.Clients.Elasticsearch.Aggregations.AggregateDictionary Aggregations { get; init; } - [JsonInclude] [JsonPropertyName("doc_count")] public long DocCount { get; init; } diff --git a/tests/Tests/Aggregations/Metric/AverageAggregationUsageTests.cs b/tests/Tests/Aggregations/Metric/AverageAggregationUsageTests.cs index 8f251fd6923..243962a2fef 100644 --- a/tests/Tests/Aggregations/Metric/AverageAggregationUsageTests.cs +++ b/tests/Tests/Aggregations/Metric/AverageAggregationUsageTests.cs @@ -62,7 +62,7 @@ public AverageAggregationUsageTests(ReadOnlyCluster i, EndpointUsage usage) : ba protected override void ExpectResponse(SearchResponse response) { response.ShouldBeValid(); - var commitsAvg = response.Aggregations.Average("average_commits"); + var commitsAvg = response.Aggregations.GetAverage("average_commits"); commitsAvg.Should().NotBeNull(); commitsAvg.Value.Should().BeGreaterThan(0); commitsAvg.Meta.Should().NotBeNull().And.HaveCount(1); diff --git a/tests/Tests/AsyncSearch/AsyncSearchApiTests.cs b/tests/Tests/AsyncSearch/AsyncSearchApiTests.cs index 6656ae28407..e279b65932a 100644 --- a/tests/Tests/AsyncSearch/AsyncSearchApiTests.cs +++ b/tests/Tests/AsyncSearch/AsyncSearchApiTests.cs @@ -158,7 +158,7 @@ public async Task AsyncSearchGetResponse() => await Assert(stream); + [U] + public void CanDeserialize_TermsAggregate_WithSubAggregation() + { + var json = @"{""aggregations"":{""terms#my-agg-name"":{""doc_count_error_upper_bound"":0,""sum_other_doc_count"":0,""buckets"":[{""key"":""foo"",""doc_count"":5,""avg#my-sub-agg-name"":{""value"":75.0}}]}}}"; - // search.Aggregations.Should().HaveCount(1); + var response = DeserializeJsonString>(json); - // search.Aggregations.TryGetStringTerms("my-agg-name", out var stringTermsAggregate).Should().BeFalse(); - // stringTermsAggregate.Should().BeNull(); - //} + var termsAgg = response.Aggregations.GetTerms("my-agg-name"); + var avgAgg = termsAgg.Buckets.Item2.Single().GetAverage("my-sub-agg-name"); + avgAgg.Value.Should().Be(75.0); + } }