Skip to content

Commit c105041

Browse files
Fix GetTerms and sub-aggregations (#6627) (#6630)
Co-authored-by: Steve Gordon <sgordon@hotmail.co.uk>
1 parent b5a5cd7 commit c105041

File tree

5 files changed

+53
-41
lines changed

5 files changed

+53
-41
lines changed

src/Elastic.Clients.Elasticsearch/Types/Aggregations/AggregateDictionary.cs

+35-24
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,35 @@ public partial class AggregateDictionary
1414

1515
public bool IsEmptyTerms(string key) => !BackingDictionary.TryGetValue(key, out var agg) || agg is EmptyTermsAggregate;
1616

17-
public bool TryGetStringTerms(string key, out StringTermsAggregate? aggregate)
18-
{
19-
aggregate = null;
20-
21-
if (BackingDictionary.TryGetValue(key, out var agg) && agg is StringTermsAggregate stringTermsAgg)
22-
{
23-
aggregate = stringTermsAgg;
24-
return true;
25-
}
26-
27-
return false;
28-
}
29-
30-
public AvgAggregate? Average(string key) => TryGet<AvgAggregate?>(key);
31-
32-
public TermsAggregate<string> Terms(string key) => Terms<string>(key);
33-
34-
public TermsAggregate<TKey> Terms<TKey>(string key)
17+
// This should be autogenerated if we want to include this.
18+
//public bool TryGetStringTerms(string key, out StringTermsAggregate? aggregate)
19+
//{
20+
// aggregate = null;
21+
22+
// if (BackingDictionary.TryGetValue(key, out var agg) && agg is StringTermsAggregate stringTermsAgg)
23+
// {
24+
// aggregate = stringTermsAgg;
25+
// return true;
26+
// }
27+
28+
// return false;
29+
//}
30+
31+
public AvgAggregate? GetAverage(string key) => TryGet<AvgAggregate?>(key);
32+
33+
/// <summary>
34+
/// WARNING: EXPERIMENTAL API
35+
/// <para>This API provides simplified access to terms aggregations.</para>
36+
/// </summary>
37+
/// <remarks>Experimental APIs are subject to changes or removal and should be used with caution.</remarks>
38+
public TermsAggregate<string> GetTerms(string key) => GetTerms<string>(key);
39+
40+
/// <summary>
41+
/// WARNING: EXPERIMENTAL API
42+
/// <para>This API provides simplified access to terms aggregations.</para>
43+
/// </summary>
44+
/// <remarks>Experimental APIs are subject to changes or removal and should be used with caution.</remarks>
45+
public TermsAggregate<TKey> GetTerms<TKey>(string key)
3546
{
3647
if (!BackingDictionary.TryGetValue(key, out var agg))
3748
{
@@ -59,12 +70,12 @@ public TermsAggregate<TKey> Terms<TKey>(string key)
5970
{
6071
var key = item.Key;
6172
var value = item.Value;
62-
dict.Add(key, new TermsBucket<TKey> { DocCount = value.DocCount, DocCountError = value.DocCountError, Key = GetKeyFromBucketKey<TKey>(value.Key), KeyAsString = value.Key });
73+
dict.Add(key, new TermsBucket<TKey>(value.BackingDictionary) { DocCount = value.DocCount, DocCountError = value.DocCountError, Key = GetKeyFromBucketKey<TKey>(value.Key), KeyAsString = value.Key });
6374
}
6475
buckets = new(dict);
6576
}, a =>
6677
{
67-
buckets = new(a.Select(b => new TermsBucket<TKey> { DocCount = b.DocCount, DocCountError = b.DocCountError, Key = GetKeyFromBucketKey<TKey>(b.Key), KeyAsString = b.Key }).ToReadOnlyCollection());
78+
buckets = new(a.Select(b => new TermsBucket<TKey>(b.BackingDictionary) { DocCount = b.DocCount, DocCountError = b.DocCountError, Key = GetKeyFromBucketKey<TKey>(b.Key), KeyAsString = b.Key }).ToReadOnlyCollection());
6879
});
6980

7081
return new TermsAggregate<TKey>
@@ -83,12 +94,12 @@ public TermsAggregate<TKey> Terms<TKey>(string key)
8394
{
8495
var key = item.Key;
8596
var value = item.Value;
86-
dict.Add(key, new TermsBucket<TKey> { DocCount = value.DocCount, DocCountError = value.DocCountError, Key = GetKeyFromBucketKey<TKey>(value.Key), KeyAsString = value.KeyAsString });
97+
dict.Add(key, new TermsBucket<TKey>(value.BackingDictionary) { DocCount = value.DocCount, DocCountError = value.DocCountError, Key = GetKeyFromBucketKey<TKey>(value.Key), KeyAsString = value.KeyAsString });
8798
}
8899
buckets = new(dict);
89100
}, a =>
90101
{
91-
buckets = new(a.Select(b => new TermsBucket<TKey> { DocCount = b.DocCount, DocCountError = b.DocCountError, Key = GetKeyFromBucketKey<TKey>(b.Key), KeyAsString = b.KeyAsString }).ToReadOnlyCollection());
102+
buckets = new(a.Select(b => new TermsBucket<TKey>(b.BackingDictionary) { DocCount = b.DocCount, DocCountError = b.DocCountError, Key = GetKeyFromBucketKey<TKey>(b.Key), KeyAsString = b.KeyAsString }).ToReadOnlyCollection());
92103
});
93104

94105
return new TermsAggregate<TKey>
@@ -107,12 +118,12 @@ public TermsAggregate<TKey> Terms<TKey>(string key)
107118
{
108119
var key = item.Key;
109120
var value = item.Value;
110-
dict.Add(key, new TermsBucket<TKey> { DocCount = value.DocCount, DocCountError = value.DocCountError, Key = GetKeyFromBucketKey<TKey>(value.Key), KeyAsString = value.KeyAsString });
121+
dict.Add(key, new TermsBucket<TKey>(value.BackingDictionary) { DocCount = value.DocCount, DocCountError = value.DocCountError, Key = GetKeyFromBucketKey<TKey>(value.Key), KeyAsString = value.KeyAsString });
111122
}
112123
buckets = new(dict);
113124
}, a =>
114125
{
115-
buckets = new(a.Select(b => new TermsBucket<TKey> { DocCount = b.DocCount, DocCountError = b.DocCountError, Key = GetKeyFromBucketKey<TKey>(b.Key), KeyAsString = b.KeyAsString }).ToReadOnlyCollection());
126+
buckets = new(a.Select(b => new TermsBucket<TKey>(b.BackingDictionary) { DocCount = b.DocCount, DocCountError = b.DocCountError, Key = GetKeyFromBucketKey<TKey>(b.Key), KeyAsString = b.KeyAsString }).ToReadOnlyCollection());
116127
});
117128

118129
return new TermsAggregate<TKey>

src/Elastic.Clients.Elasticsearch/Types/Aggregations/TermsBucket.cs

+7-5
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,25 @@
22
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
33
// See the LICENSE file in the project root for more information.
44

5+
using System.Collections.Generic;
56
using System.Text.Json.Serialization;
67

78
namespace Elastic.Clients.Elasticsearch.Aggregations;
89

9-
public sealed class TermsBucket<TKey>
10+
public sealed class TermsBucket<TKey> : AggregateDictionary
1011
{
12+
public TermsBucket(IReadOnlyDictionary<string, IAggregate> backingDictionary) : base(backingDictionary)
13+
{
14+
}
15+
1116
public TKey Key { get; init; }
17+
1218
public string? KeyAsString { get; init; }
1319

1420
[JsonInclude]
1521
[JsonPropertyName("doc_count_error")]
1622
public long? DocCountError { get; init; }
1723

18-
[JsonInclude]
19-
[JsonPropertyName("aggregations")]
20-
public Elastic.Clients.Elasticsearch.Aggregations.AggregateDictionary Aggregations { get; init; }
21-
2224
[JsonInclude]
2325
[JsonPropertyName("doc_count")]
2426
public long DocCount { get; init; }

tests/Tests/Aggregations/Metric/AverageAggregationUsageTests.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public AverageAggregationUsageTests(ReadOnlyCluster i, EndpointUsage usage) : ba
6262
protected override void ExpectResponse(SearchResponse<Project> response)
6363
{
6464
response.ShouldBeValid();
65-
var commitsAvg = response.Aggregations.Average("average_commits");
65+
var commitsAvg = response.Aggregations.GetAverage("average_commits");
6666
commitsAvg.Should().NotBeNull();
6767
commitsAvg.Value.Should().BeGreaterThan(0);
6868
commitsAvg.Meta.Should().NotBeNull().And.HaveCount(1);

tests/Tests/AsyncSearch/AsyncSearchApiTests.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ public async Task AsyncSearchGetResponse() => await Assert<GetAsyncSearchRespons
158158
r.Response.Should().NotBeNull();
159159
r.Response.Took.Should().BeGreaterOrEqualTo(0);
160160
r.Response.Hits.Should().HaveCount(10);
161-
var terms = r.Response.Aggregations.Terms("states");
161+
var terms = r.Response.Aggregations.GetTerms("states");
162162
terms.Should().NotBeNull();
163163
});
164164

tests/Tests/Serialization/Aggregations/TermsAggregateDeserializationTests.cs

+9-10
Original file line numberDiff line numberDiff line change
@@ -193,16 +193,15 @@ public void CanDeserialize_BasicEmptyTermsAggregate()
193193
}
194194
}
195195

196-
//[U]
197-
//public void TryGetStringTermsAggregate()
198-
//{
199-
// var stream = WrapInStream(@"{""aggregations"":{""terms#my-agg-name"":{""doc_count_error_upper_bound"":10,""sum_other_doc_count"":200,""buckets"":[]}}}");
200-
201-
// var search = _requestResponseSerializer.Deserialize<BasicSearchResponse>(stream);
196+
[U]
197+
public void CanDeserialize_TermsAggregate_WithSubAggregation()
198+
{
199+
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}}]}}}";
202200

203-
// search.Aggregations.Should().HaveCount(1);
201+
var response = DeserializeJsonString<SearchResponse<object>>(json);
204202

205-
// search.Aggregations.TryGetStringTerms("my-agg-name", out var stringTermsAggregate).Should().BeFalse();
206-
// stringTermsAggregate.Should().BeNull();
207-
//}
203+
var termsAgg = response.Aggregations.GetTerms("my-agg-name");
204+
var avgAgg = termsAgg.Buckets.Item2.Single().GetAverage("my-sub-agg-name");
205+
avgAgg.Value.Should().Be(75.0);
206+
}
208207
}

0 commit comments

Comments
 (0)