Skip to content

Commit 7f93d1b

Browse files
committed
fix #2105 allow AggregationContainerDescriptor's to be && together
1 parent 98558a4 commit 7f93d1b

File tree

4 files changed

+80
-13
lines changed

4 files changed

+80
-13
lines changed

src/Nest/Aggregations/AggregationContainer.cs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4-
using Newtonsoft.Json;
54
using Nest.Aggregations.Visitor;
5+
using Newtonsoft.Json;
66

77
namespace Nest
88
{
@@ -608,5 +608,31 @@ public void Accept(IAggregationVisitor visitor)
608608
if (visitor.Scope == AggregationVisitorScope.Unknown) visitor.Scope = AggregationVisitorScope.Aggregation;
609609
new AggregationWalker().Walk(this, visitor);
610610
}
611+
612+
//always evaluate to false so that each side of && equation is evaluated
613+
public static bool operator false(AggregationContainerDescriptor<T> a) => false;
614+
615+
//always evaluate to false so that each side of && equation is evaluated
616+
public static bool operator true(AggregationContainerDescriptor<T> a) => false;
617+
618+
619+
public static AggregationContainerDescriptor<T> operator &(AggregationContainerDescriptor<T> left, AggregationContainerDescriptor<T> right)
620+
{
621+
var d = new AggregationContainerDescriptor<T>();
622+
var leftAggs = (IDictionary<string, IAggregationContainer>)((IAggregationContainer)left).Aggregations;
623+
var rightAggs = (IDictionary<string, IAggregationContainer>)((IAggregationContainer)right).Aggregations;
624+
foreach(var kv in rightAggs)
625+
{
626+
if (leftAggs.ContainsKey(kv.Key))
627+
{
628+
var message = $"Can not merge two {nameof(AggregationContainerDescriptor<T>)}'s";
629+
message += $" {kv.Key} is defined in both";
630+
throw new Exception(message);
631+
}
632+
leftAggs.Add(kv.Key, kv.Value);
633+
}
634+
((IAggregationContainer)d).Aggregations = ((IAggregationContainer)left).Aggregations;
635+
return d;
636+
}
611637
}
612638
}

src/Nest/CommonAbstractions/DictionaryLike/IsADictionaryDescriptorBase.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ public interface IIsADictionary { }
77

88
public interface IIsADictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary, IIsADictionary
99
{
10-
10+
1111
}
1212

13-
public abstract class IsADictionaryDescriptorBase<TDescriptor, TInterface, TKey, TValue>
13+
public abstract class IsADictionaryDescriptorBase<TDescriptor, TInterface, TKey, TValue>
1414
: DescriptorPromiseBase<TDescriptor, TInterface>
1515
where TDescriptor : IsADictionaryDescriptorBase<TDescriptor, TInterface, TKey, TValue>
1616
where TInterface : class, IIsADictionary<TKey, TValue>
@@ -21,4 +21,4 @@ protected IsADictionaryDescriptorBase(TInterface instance) : base(instance) {}
2121
protected TDescriptor Assign(TKey key, TValue value) => Assign(a => a.Add(key, value));
2222

2323
}
24-
}
24+
}

src/Tests/Aggregations/Bucket/Children/ChildrenAggregationUsageTests.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using Nest;
33
using Tests.Framework.Integration;
44
using Tests.Framework.MockData;
5-
using static Nest.Infer;
65

76
namespace Tests.Aggregations.Bucket.Children
87
{
@@ -32,6 +31,10 @@ public ChildrenAggregationUsageTests(ReadOnlyCluster i, EndpointUsage usage) : b
3231
max_per_child = new
3332
{
3433
max = new { field = "confidenceFactor" }
34+
},
35+
min_per_child = new
36+
{
37+
min = new { field = "confidenceFactor" }
3538
}
3639
}
3740
}
@@ -44,6 +47,7 @@ public ChildrenAggregationUsageTests(ReadOnlyCluster i, EndpointUsage usage) : b
4447
.Aggregations(childAggs => childAggs
4548
.Average("average_per_child", avg => avg.Field(p => p.ConfidenceFactor))
4649
.Max("max_per_child", avg => avg.Field(p => p.ConfidenceFactor))
50+
.Min("min_per_child", avg => avg.Field(p => p.ConfidenceFactor))
4751
)
4852
)
4953
);
@@ -54,8 +58,9 @@ public ChildrenAggregationUsageTests(ReadOnlyCluster i, EndpointUsage usage) : b
5458
Aggregations = new ChildrenAggregation("name_of_child_agg", typeof(CommitActivity))
5559
{
5660
Aggregations =
57-
new AverageAggregation("average_per_child", "confidenceFactor") &&
58-
new MaxAggregation("max_per_child", "confidenceFactor")
61+
new AverageAggregation("average_per_child", "confidenceFactor")
62+
&& new MaxAggregation("max_per_child", "confidenceFactor")
63+
&& new MinAggregation("min_per_child", "confidenceFactor")
5964
}
6065
};
6166
}

src/Tests/Aggregations/WritingAggregations.doc.cs

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
using System;
2-
using Nest;
3-
using Tests.Framework;
4-
using Tests.Framework.MockData;
5-
using static Nest.Infer;
62
using System.Collections.Generic;
73
using System.Linq;
4+
using FluentAssertions;
5+
using Nest;
86
using Tests.Aggregations.Bucket.Children;
7+
using Tests.Framework;
98
using Tests.Framework.Integration;
10-
using FluentAssertions;
9+
using Tests.Framework.MockData;
10+
using static Nest.Infer;
1111

1212
namespace Tests.Aggregations
1313
{
@@ -52,6 +52,13 @@ public class Usage : UsageTestBase<ISearchRequest, SearchDescriptor<Project>, Se
5252
{
5353
field = "confidenceFactor"
5454
}
55+
},
56+
min_per_child = new
57+
{
58+
min = new
59+
{
60+
field = "confidenceFactor"
61+
}
5562
}
5663
}
5764
}
@@ -68,6 +75,7 @@ public class Usage : UsageTestBase<ISearchRequest, SearchDescriptor<Project>, Se
6875
.Aggregations(childAggs => childAggs
6976
.Average("average_per_child", avg => avg.Field(p => p.ConfidenceFactor))
7077
.Max("max_per_child", avg => avg.Field(p => p.ConfidenceFactor))
78+
.Min("min_per_child", avg => avg.Field(p => p.ConfidenceFactor))
7179
)
7280
)
7381
);
@@ -85,6 +93,7 @@ public class Usage : UsageTestBase<ISearchRequest, SearchDescriptor<Project>, Se
8593
Aggregations =
8694
new AverageAggregation("average_per_child", "confidenceFactor")
8795
&& new MaxAggregation("max_per_child", "confidenceFactor")
96+
&& new MinAggregation("min_per_child", "confidenceFactor")
8897
}
8998
};
9099
}
@@ -106,6 +115,7 @@ public class AggregationDslUsage : Usage
106115
Aggregations =
107116
new AverageAggregation("average_per_child", Field<CommitActivity>(p => p.ConfidenceFactor))
108117
&& new MaxAggregation("max_per_child", Field<CommitActivity>(p => p.ConfidenceFactor))
118+
&& new MinAggregation("min_per_child", Field<CommitActivity>(p => p.ConfidenceFactor))
109119
}
110120
};
111121
}
@@ -125,7 +135,8 @@ protected override Func<SearchDescriptor<Project>, ISearchRequest> Fluent
125135
var aggregations = new List<Func<AggregationContainerDescriptor<CommitActivity>, IAggregationContainer>> //<1> a list of aggregation functions to apply
126136
{
127137
a => a.Average("average_per_child", avg => avg.Field(p => p.ConfidenceFactor)),
128-
a => a.Max("max_per_child", avg => avg.Field(p => p.ConfidenceFactor))
138+
a => a.Max("max_per_child", avg => avg.Field(p => p.ConfidenceFactor)),
139+
a => a.Min("min_per_child", avg => avg.Field(p => p.ConfidenceFactor))
129140
};
130141

131142
return s => s
@@ -140,6 +151,30 @@ protected override Func<SearchDescriptor<Project>, ISearchRequest> Fluent
140151
}
141152
}
142153

154+
public class AndMultipleDescriptorsUsage : Usage
155+
{
156+
/**
157+
* Combining multipe `AggregationDescriptor`'s is also possible using the bitwise `&` operator
158+
*/
159+
protected override Func<SearchDescriptor<Project>, ISearchRequest> Fluent
160+
{
161+
get
162+
{
163+
var aggregations = new AggregationContainerDescriptor<CommitActivity>()
164+
.Average("average_per_child", avg => avg.Field(p => p.ConfidenceFactor))
165+
.Max("max_per_child", avg => avg.Field(p => p.ConfidenceFactor))
166+
&& new AggregationContainerDescriptor<CommitActivity>()
167+
.Min("min_per_child", avg => avg.Field(p => p.ConfidenceFactor));
168+
169+
return s => s
170+
.Aggregations(aggs => aggs
171+
.Children<CommitActivity>("name_of_child_agg", child => child
172+
.Aggregations(childAggs => aggregations)
173+
)
174+
);
175+
}
176+
}
177+
}
143178
/**[[aggs-vs-aggregations]]
144179
*=== Aggs vs. Aggregations
145180
*
@@ -161,6 +196,7 @@ public AggsUsage(ReadOnlyCluster i, EndpointUsage usage) : base(i, usage) { }
161196
.Aggregations(childAggs => childAggs
162197
.Average("average_per_child", avg => avg.Field(p => p.ConfidenceFactor))
163198
.Max("max_per_child", avg => avg.Field(p => p.ConfidenceFactor))
199+
.Min("min_per_child", avg => avg.Field(p => p.ConfidenceFactor))
164200
)
165201
)
166202
);

0 commit comments

Comments
 (0)