Skip to content

Commit 6fdf57a

Browse files
Added diversified sampler aggregation (#5031)
Co-authored-by: Martijn Laarman <Mpdreamz@gmail.com>
1 parent 3d8f6ec commit 6fdf57a

File tree

7 files changed

+234
-8
lines changed

7 files changed

+234
-8
lines changed

src/Nest/Aggregations/AggregateDictionary.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ public FiltersAggregate Filters(string key)
133133

134134
public SingleBucketAggregate Sampler(string key) => TryGet<SingleBucketAggregate>(key);
135135

136+
public SingleBucketAggregate DiversifiedSampler(string key) => TryGet<SingleBucketAggregate>(key);
137+
136138
public GeoCentroidAggregate GeoCentroid(string key) => TryGet<GeoCentroidAggregate>(key);
137139

138140
public SignificantTermsAggregate<TKey> SignificantTerms<TKey>(string key)

src/Nest/Aggregations/AggregationContainer.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ public interface IAggregationContainer
135135
[DataMember(Name = "derivative")]
136136
IDerivativeAggregation Derivative { get; set; }
137137

138+
[DataMember(Name = "diversified_sampler")]
139+
IDiversifiedSamplerAggregation DiversifiedSampler { get; set; }
140+
138141
[DataMember(Name = "extended_stats")]
139142
IExtendedStatsAggregation ExtendedStats { get; set; }
140143

@@ -324,6 +327,8 @@ public class AggregationContainer : IAggregationContainer
324327

325328
public IDerivativeAggregation Derivative { get; set; }
326329

330+
public IDiversifiedSamplerAggregation DiversifiedSampler { get; set; }
331+
327332
public IExtendedStatsAggregation ExtendedStats { get; set; }
328333

329334
public IExtendedStatsBucketAggregation ExtendedStatsBucket { get; set; }
@@ -485,6 +490,8 @@ public class AggregationContainerDescriptor<T> : DescriptorBase<AggregationConta
485490

486491
IDerivativeAggregation IAggregationContainer.Derivative { get; set; }
487492

493+
IDiversifiedSamplerAggregation IAggregationContainer.DiversifiedSampler { get; set; }
494+
488495
IExtendedStatsAggregation IAggregationContainer.ExtendedStats { get; set; }
489496

490497
IExtendedStatsBucketAggregation IAggregationContainer.ExtendedStatsBucket { get; set; }
@@ -860,6 +867,11 @@ Func<SamplerAggregationDescriptor<T>, ISamplerAggregation> selector
860867
) =>
861868
_SetInnerAggregation(name, selector, (a, d) => a.Sampler = d);
862869

870+
public AggregationContainerDescriptor<T> DiversifiedSampler(string name,
871+
Func<DiversifiedSamplerAggregationDescriptor<T>, IDiversifiedSamplerAggregation> selector
872+
) =>
873+
_SetInnerAggregation(name, selector, (a, d) => a.DiversifiedSampler = d);
874+
863875
public AggregationContainerDescriptor<T> GeoCentroid(string name,
864876
Func<GeoCentroidAggregationDescriptor<T>, IGeoCentroidAggregation> selector
865877
) =>
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
using System;
2+
using System.Linq.Expressions;
3+
using System.Runtime.Serialization;
4+
using Elasticsearch.Net.Utf8Json;
5+
6+
namespace Nest
7+
{
8+
[InterfaceDataContract]
9+
[ReadAs(typeof(DiversifiedSamplerAggregation))]
10+
public interface IDiversifiedSamplerAggregation : IBucketAggregation
11+
{
12+
[DataMember(Name ="execution_hint")]
13+
DiversifiedSamplerAggregationExecutionHint? ExecutionHint { get; set; }
14+
15+
[DataMember(Name = "field")]
16+
Field Field { get; set; }
17+
18+
[DataMember(Name ="max_docs_per_value")]
19+
int? MaxDocsPerValue { get; set; }
20+
21+
[DataMember(Name ="script")]
22+
IScript Script { get; set; }
23+
24+
[DataMember(Name ="shard_size")]
25+
int? ShardSize { get; set; }
26+
}
27+
28+
public class DiversifiedSamplerAggregation : BucketAggregationBase, IDiversifiedSamplerAggregation
29+
{
30+
internal DiversifiedSamplerAggregation() { }
31+
32+
public DiversifiedSamplerAggregation(string name) : base(name) { }
33+
34+
public DiversifiedSamplerAggregationExecutionHint? ExecutionHint { get; set; }
35+
public Field Field { get; set; }
36+
public int? MaxDocsPerValue { get; set; }
37+
public IScript Script { get; set; }
38+
public int? ShardSize { get; set; }
39+
40+
internal override void WrapInContainer(AggregationContainer c) => c.DiversifiedSampler = this;
41+
}
42+
43+
public class DiversifiedSamplerAggregationDescriptor<T>
44+
: BucketAggregationDescriptorBase<DiversifiedSamplerAggregationDescriptor<T>, IDiversifiedSamplerAggregation, T>, IDiversifiedSamplerAggregation
45+
where T : class
46+
{
47+
DiversifiedSamplerAggregationExecutionHint? IDiversifiedSamplerAggregation.ExecutionHint { get; set; }
48+
Field IDiversifiedSamplerAggregation.Field { get; set; }
49+
int? IDiversifiedSamplerAggregation.MaxDocsPerValue { get; set; }
50+
IScript IDiversifiedSamplerAggregation.Script { get; set; }
51+
int? IDiversifiedSamplerAggregation.ShardSize { get; set; }
52+
53+
public DiversifiedSamplerAggregationDescriptor<T> ExecutionHint(DiversifiedSamplerAggregationExecutionHint? executionHint) =>
54+
Assign(executionHint, (a, v) => a.ExecutionHint = v);
55+
56+
public DiversifiedSamplerAggregationDescriptor<T> Field(Field field) => Assign(field, (a, v) => a.Field = v);
57+
58+
public DiversifiedSamplerAggregationDescriptor<T> Field<TValue>(Expression<Func<T, TValue>> field) => Assign(field, (a, v) => a.Field = v);
59+
60+
public DiversifiedSamplerAggregationDescriptor<T> MaxDocsPerValue(int? maxDocs) => Assign(maxDocs, (a, v) => a.MaxDocsPerValue = v);
61+
62+
public DiversifiedSamplerAggregationDescriptor<T> Script(string script) => Assign((InlineScript)script, (a, v) => a.Script = v);
63+
64+
public DiversifiedSamplerAggregationDescriptor<T> Script(Func<ScriptDescriptor, IScript> scriptSelector) =>
65+
Assign(scriptSelector, (a, v) => a.Script = v?.Invoke(new ScriptDescriptor()));
66+
67+
public DiversifiedSamplerAggregationDescriptor<T> ShardSize(int? shardSize) => Assign(shardSize, (a, v) => a.ShardSize = v);
68+
}
69+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System.Runtime.Serialization;
2+
using Elasticsearch.Net;
3+
4+
namespace Nest
5+
{
6+
[StringEnum]
7+
public enum DiversifiedSamplerAggregationExecutionHint
8+
{
9+
[EnumMember(Value = "map")]
10+
Map,
11+
12+
[EnumMember(Value = "global_ordinals")]
13+
GlobalOrdinals,
14+
15+
[EnumMember(Value = "bytes_hash")]
16+
BytesHash
17+
}
18+
}

src/Nest/Aggregations/Visitor/AggregationVisitor.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ public interface IAggregationVisitor
130130

131131
void Visit(ISamplerAggregation aggregation);
132132

133+
void Visit(IDiversifiedSamplerAggregation aggregation);
134+
133135
void Visit(IGeoCentroidAggregation aggregation);
134136

135137
void Visit(ICompositeAggregation aggregation);
@@ -213,6 +215,8 @@ public virtual void Visit(IBucketScriptAggregation aggregation) { }
213215

214216
public virtual void Visit(ISamplerAggregation aggregation) { }
215217

218+
public virtual void Visit(IDiversifiedSamplerAggregation aggregation) { }
219+
216220
public virtual void Visit(IBucketSelectorAggregation aggregation) { }
217221

218222
public virtual void Visit(IBucketSortAggregation aggregation) { }

tests/Examples/Aggregations/Bucket/DiversifiedSamplerAggregationPage.cs

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,35 @@ namespace Examples.Aggregations.Bucket
1010
{
1111
public class DiversifiedSamplerAggregationPage : ExampleBase
1212
{
13-
[U(Skip = "Example not implemented")]
13+
[U]
1414
[Description("aggregations/bucket/diversified-sampler-aggregation.asciidoc:30")]
1515
public void Line30()
1616
{
1717
// tag::3344c3478f1e8bbbef683757638a34f4[]
18-
var response0 = new SearchResponse<object>();
18+
var searchResponse = client.Search<object>(s => s
19+
.Index("stackoverflow")
20+
.Query(q => q
21+
.QueryString(qs => qs
22+
.Query("tags:elasticsearch")
23+
)
24+
)
25+
.Aggregations(a => a
26+
.DiversifiedSampler("my_unbiased_sample", s => s
27+
.ShardSize(200)
28+
.Field("author")
29+
.Aggregations(agg => agg
30+
.SignificantTerms("keywords", k => k
31+
.Field("tags")
32+
.Exclude(new string[] { "elasticsearch" })
33+
)
34+
)
35+
)
36+
)
37+
.Size(0)
38+
);
1939
// end::3344c3478f1e8bbbef683757638a34f4[]
2040

21-
response0.MatchesExample(@"POST /stackoverflow/_search?size=0
41+
searchResponse.MatchesExample(@"POST /stackoverflow/_search?size=0
2242
{
2343
""query"": {
2444
""query_string"": {
@@ -41,18 +61,46 @@ public void Line30()
4161
}
4262
}
4363
}
44-
}");
64+
}", (e, b) =>
65+
{
66+
e.Uri.Query = e.Uri.Query.Replace("size=0", string.Empty);
67+
b["size"] = 0;
68+
});
4569
}
4670

47-
[U(Skip = "Example not implemented")]
71+
[U]
4872
[Description("aggregations/bucket/diversified-sampler-aggregation.asciidoc:95")]
4973
public void Line95()
5074
{
5175
// tag::07afce825c09de17a3d73a02b17a0a97[]
52-
var response0 = new SearchResponse<object>();
76+
var searchResponse = client.Search<object>(s => s
77+
.Index("stackoverflow")
78+
.Query(q => q
79+
.QueryString(qs => qs
80+
.Query("tags:kibana")
81+
)
82+
)
83+
.Aggregations(a => a
84+
.DiversifiedSampler("my_unbiased_sample", s => s
85+
.ShardSize(200)
86+
.MaxDocsPerValue(3)
87+
.Script(sc => sc
88+
.Source("doc['tags'].hashCode()")
89+
.Lang("painless")
90+
)
91+
.Aggregations(agg => agg
92+
.SignificantTerms("keywords", k => k
93+
.Field("tags")
94+
.Exclude(new string[] { "kibana" })
95+
)
96+
)
97+
)
98+
)
99+
.Size(0)
100+
);
53101
// end::07afce825c09de17a3d73a02b17a0a97[]
54102

55-
response0.MatchesExample(@"POST /stackoverflow/_search?size=0
103+
searchResponse.MatchesExample(@"POST /stackoverflow/_search?size=0
56104
{
57105
""query"": {
58106
""query_string"": {
@@ -79,7 +127,11 @@ public void Line95()
79127
}
80128
}
81129
}
82-
}");
130+
}", (e, b) =>
131+
{
132+
e.Uri.Query = e.Uri.Query.Replace("size=0", string.Empty);
133+
b["size"] = 0;
134+
});
83135
}
84136
}
85137
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Licensed to Elasticsearch B.V under one or more agreements.
2+
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
3+
// See the LICENSE file in the project root for more information
4+
5+
using System;
6+
using Elastic.Elasticsearch.Xunit.XunitPlumbing;
7+
using Nest;
8+
using Tests.Core.ManagedElasticsearch.Clusters;
9+
using Tests.Domain;
10+
using Tests.Framework.EndpointTests.TestState;
11+
12+
namespace Tests.Aggregations.Bucket.DiversifiedSampler
13+
{
14+
[SkipVersion("<7.9.0", "introduced in 7.9.0")]
15+
public class DiversifiedSamplerAggregationUsageTests : AggregationUsageTestBase
16+
{
17+
public DiversifiedSamplerAggregationUsageTests(ReadOnlyCluster i, EndpointUsage usage) : base(i, usage) { }
18+
19+
protected override object AggregationJson => new
20+
{
21+
diversified_sample = new
22+
{
23+
diversified_sampler = new
24+
{
25+
execution_hint = "global_ordinals",
26+
field = "type",
27+
max_docs_per_value = 10,
28+
shard_size = 200
29+
},
30+
aggs = new
31+
{
32+
significant_names = new
33+
{
34+
significant_terms = new
35+
{
36+
field = "name"
37+
}
38+
}
39+
}
40+
}
41+
};
42+
43+
protected override Func<AggregationContainerDescriptor<Project>, IAggregationContainer> FluentAggs => a => a
44+
.DiversifiedSampler("diversified_sample", sm => sm
45+
.ExecutionHint(DiversifiedSamplerAggregationExecutionHint.GlobalOrdinals)
46+
.Field(doc => doc.Type)
47+
.MaxDocsPerValue(10)
48+
.ShardSize(200)
49+
.Aggregations(aa => aa
50+
.SignificantTerms("significant_names", st => st
51+
.Field(p => p.Name)
52+
)
53+
)
54+
);
55+
56+
protected override AggregationDictionary InitializerAggs =>
57+
new DiversifiedSamplerAggregation("diversified_sample")
58+
{
59+
ExecutionHint = DiversifiedSamplerAggregationExecutionHint.GlobalOrdinals,
60+
Field = new Field("type"),
61+
MaxDocsPerValue = 10,
62+
ShardSize = 200,
63+
Aggregations = new SignificantTermsAggregation("significant_names")
64+
{
65+
Field = "name"
66+
}
67+
};
68+
}
69+
}

0 commit comments

Comments
 (0)