Skip to content

Commit f2f4a84

Browse files
committed
Reverse nested aggregation support
Closes #828
1 parent 17247a8 commit f2f4a84

File tree

5 files changed

+106
-0
lines changed

5 files changed

+106
-0
lines changed

Diff for: src/Nest/DSL/Aggregations/AggregationDescriptor.cs

+17
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ public interface IAggregationContainer
6060
[JsonProperty("nested")]
6161
INestedAggregator Nested { get; set; }
6262

63+
[JsonProperty("reverse_nested")]
64+
IReverseNestedAggregator ReverseNested { get; set; }
65+
6366
[JsonProperty("range")]
6467
IRangeAggregator Range { get; set; }
6568

@@ -102,6 +105,7 @@ public class AggregationContainer : IAggregationContainer
102105
private ICardinalityAggregator _cardinality;
103106
private IMissingAggregator _missing;
104107
private INestedAggregator _nested;
108+
private IReverseNestedAggregator _reverseNested;
105109
private IRangeAggregator _range;
106110
private ITermsAggregator _terms;
107111
private ISignificantTermsAggregator _significantTerms;
@@ -193,6 +197,12 @@ public INestedAggregator Nested
193197
set { _nested = value; }
194198
}
195199

200+
public IReverseNestedAggregator ReverseNested
201+
{
202+
get { return _reverseNested; }
203+
set { _reverseNested = value; }
204+
}
205+
196206
public IRangeAggregator Range
197207
{
198208
get { return _range; }
@@ -264,6 +274,8 @@ public class AggregationDescriptor<T> : IAggregationContainer
264274
IMissingAggregator IAggregationContainer.Missing { get; set; }
265275

266276
INestedAggregator IAggregationContainer.Nested { get; set; }
277+
278+
IReverseNestedAggregator IAggregationContainer.ReverseNested { get; set; }
267279

268280
IRangeAggregator IAggregationContainer.Range { get; set; }
269281

@@ -381,6 +393,11 @@ public AggregationDescriptor<T> Nested(string name, Func<NestedAggregationDescri
381393
return _SetInnerAggregation(name, selector, (a, d) => a.Nested = d);
382394
}
383395

396+
public AggregationDescriptor<T> ReverseNested(string name, Func<ReverseNestedAggregationDescriptor<T>, ReverseNestedAggregationDescriptor<T>> selector)
397+
{
398+
return _SetInnerAggregation(name, selector, (a, d) => a.ReverseNested = d);
399+
}
400+
384401
public AggregationDescriptor<T> Range(string name, Func<RangeAggregationDescriptor<T>, RangeAggregationDescriptor<T>> selector)
385402
{
386403
return _SetInnerAggregation(name, selector, (a, d) => a.Range = d);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using Nest.Resolvers.Converters;
2+
using Newtonsoft.Json;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Linq.Expressions;
7+
using System.Text;
8+
9+
namespace Nest
10+
{
11+
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
12+
[JsonConverter(typeof(ReadAsTypeConverter<ReverseNestedAggregator>))]
13+
public interface IReverseNestedAggregator : IBucketAggregator
14+
{
15+
[JsonProperty("path")]
16+
PropertyPathMarker Path { get; set; }
17+
}
18+
19+
public class ReverseNestedAggregator : BucketAggregator, IReverseNestedAggregator
20+
{
21+
[JsonProperty("path")]
22+
public PropertyPathMarker Path { get; set; }
23+
}
24+
25+
public class ReverseNestedAggregationDescriptor<T>
26+
: BucketAggregationBaseDescriptor<ReverseNestedAggregationDescriptor<T>, T>, IReverseNestedAggregator
27+
where T : class
28+
{
29+
IReverseNestedAggregator Self { get { return this; } }
30+
PropertyPathMarker IReverseNestedAggregator.Path { get; set; }
31+
32+
public ReverseNestedAggregationDescriptor<T> Path(string path)
33+
{
34+
this.Self.Path = path;
35+
return this;
36+
}
37+
38+
public ReverseNestedAggregationDescriptor<T> Path(Expression<Func<T, object>> path)
39+
{
40+
this.Self.Path = path;
41+
return this;
42+
}
43+
}
44+
}

Diff for: src/Nest/Domain/Aggregations/AggregationsHelper.cs

+5
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,11 @@ public SingleBucket Nested(string key)
101101
return this.TryGet<SingleBucket>(key);
102102
}
103103

104+
public SingleBucket ReverseNested(string key)
105+
{
106+
return this.TryGet<SingleBucket>(key);
107+
}
108+
104109
public BucketWithDocCount<SignificantTermItem> SignificantTerms(string key)
105110
{
106111
var bucket = this.TryGet<BucketWithDocCount>(key);

Diff for: src/Nest/Nest.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@
212212
<Compile Include="Domain\Stats\SegmentsStats.cs" />
213213
<Compile Include="DSL\Aggregations\PercentileRanksAggregationDescriptor.cs" />
214214
<Compile Include="DSL\Aggregations\GeoBoundsAggregationDescriptor.cs" />
215+
<Compile Include="DSL\Aggregations\ReverseNestedAggregationDescriptor.cs" />
215216
<Compile Include="DSL\CatIndicesDescriptor.cs" />
216217
<Compile Include="DSL\CatShardsDescriptor.cs" />
217218
<Compile Include="DSL\CatThreadPoolDescriptor.cs" />

Diff for: src/Tests/Nest.Tests.Integration/Aggregations/NestedBucketAggregationTests.cs

+39
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,44 @@ public void Terms()
4545
.And.BeGreaterOrEqualTo(18);
4646
}
4747

48+
[Test]
49+
public void ReverseNested()
50+
{
51+
var results = this.Client.Search<ElasticsearchProject>(s => s
52+
.Size(0)
53+
.Aggregations(a => a
54+
.Nested("contributors", n => n
55+
.Path(p => p.Contributors)
56+
.Aggregations(t => t
57+
.Terms("ages", m => m
58+
.Field(p => p.Contributors.First().Age)
59+
.Aggregations(aa => aa
60+
.ReverseNested("contributor_to_project", rn => rn
61+
.Aggregations(aaa => aaa
62+
.Terms("countries_per_age", tt => tt
63+
.Field(p => p.Country)
64+
)
65+
)
66+
)
67+
)
68+
)
69+
)
70+
)
71+
)
72+
);
73+
74+
results.IsValid.Should().BeTrue();
75+
var contributors = results.Aggs.Nested("contributors");
76+
var ages = contributors.Aggregations["ages"] as Bucket;
77+
78+
foreach (var item in ages.Items)
79+
{
80+
var age = item as KeyItem;
81+
age.Key.Should().NotBeNullOrWhiteSpace();
82+
var contributorToProject = age.Aggregations["contributor_to_project"] as SingleBucket;
83+
var countriesPerAge = contributorToProject.Terms("countries_per_age");
84+
countriesPerAge.Items.Count().Should().BeGreaterThan(0);
85+
}
86+
}
4887
}
4988
}

0 commit comments

Comments
 (0)