-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Relates: elastic/elasticsearch#34210 This commit adds Parent Aggregation to the high level client.
- Loading branch information
Showing
8 changed files
with
297 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
98 changes: 98 additions & 0 deletions
98
docs/aggregations/bucket/parent/parent-aggregation-usage.asciidoc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
:ref_current: https://www.elastic.co/guide/en/elasticsearch/reference/6.5 | ||
|
||
:github: https://github.com/elastic/elasticsearch-net | ||
|
||
:nuget: https://www.nuget.org/packages | ||
|
||
//// | ||
IMPORTANT NOTE | ||
============== | ||
This file has been generated from https://github.com/elastic/elasticsearch-net/tree/6.x/src/Tests/Tests/Aggregations/Bucket/Parent/ParentAggregationUsageTests.cs. | ||
If you wish to submit a PR for any spelling mistakes, typos or grammatical errors for this file, | ||
please modify the original csharp file found at the link and submit the PR with that change. Thanks! | ||
//// | ||
|
||
[[parent-aggregation-usage]] | ||
=== Parent Aggregation Usage | ||
|
||
A special single bucket aggregation that selects parent documents that have the specified type, as defined in a `join` field. | ||
|
||
Be sure to read the Elasticsearch documentation on {ref_current}/search-aggregations-bucket-parent-aggregation.html[Parent Aggregation]. | ||
|
||
==== Fluent DSL example | ||
|
||
[source,csharp] | ||
---- | ||
a => a | ||
.Parent<Project>("name_of_parent_agg", parent => parent <1> | ||
.Aggregations(parentAggs => parentAggs | ||
.Average("average_commits", avg => avg.Field(p => p.NumberOfCommits)) | ||
.Max("max_commits", avg => avg.Field(p => p.NumberOfCommits)) | ||
.Min("min_commits", avg => avg.Field(p => p.NumberOfCommits)) | ||
) | ||
) | ||
---- | ||
<1> sub-aggregations are on the type determined from the generic type parameter. In this example, the search is against `CommitActivity` type and `Project` is a parent of `CommitActivity` | ||
|
||
==== Object Initializer syntax example | ||
|
||
[source,csharp] | ||
---- | ||
new ParentAggregation("name_of_parent_agg", typeof(CommitActivity)) <1> | ||
{ | ||
Aggregations = | ||
new AverageAggregation("average_commits", Field<Project>(f => f.NumberOfCommits)) <2> | ||
&& new MaxAggregation("max_commits", Field<Project>(f => f.NumberOfCommits)) | ||
&& new MinAggregation("min_commits", Field<Project>(f => f.NumberOfCommits)) | ||
} | ||
---- | ||
<1> `join` field is determined from the _child_ type. In this example, it is `CommitActivity` | ||
|
||
<2> sub-aggregations are on the type determined from the `join` field. In this example, a `Project` is a parent of `CommitActivity` | ||
|
||
[source,javascript] | ||
.Example json output | ||
---- | ||
{ | ||
"size": 0, | ||
"aggs": { | ||
"name_of_parent_agg": { | ||
"parent": { | ||
"type": "commits" | ||
}, | ||
"aggs": { | ||
"average_commits": { | ||
"avg": { | ||
"field": "numberOfCommits" | ||
} | ||
}, | ||
"max_commits": { | ||
"max": { | ||
"field": "numberOfCommits" | ||
} | ||
}, | ||
"min_commits": { | ||
"min": { | ||
"field": "numberOfCommits" | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
---- | ||
|
||
==== Handling Responses | ||
|
||
[source,csharp] | ||
---- | ||
response.ShouldBeValid(); | ||
var parentAgg = response.Aggregations.Parent("name_of_parent_agg"); | ||
parentAgg.Should().NotBeNull(); | ||
parentAgg.DocCount.Should().BeGreaterThan(0); | ||
parentAgg.Min("average_commits").Should().NotBeNull(); | ||
parentAgg.Min("min_commits").Should().NotBeNull(); | ||
parentAgg.Max("max_commits").Should().NotBeNull(); | ||
---- | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
using Newtonsoft.Json; | ||
|
||
namespace Nest | ||
{ | ||
[JsonObject(MemberSerialization = MemberSerialization.OptIn)] | ||
[ContractJsonConverter(typeof(AggregationJsonConverter<ParentAggregation>))] | ||
public interface IParentAggregation : IBucketAggregation | ||
{ | ||
/// <summary> | ||
/// The type for the child in the parent/child relationship | ||
/// </summary> | ||
[JsonProperty("type")] | ||
RelationName Type { get; set; } | ||
} | ||
|
||
public class ParentAggregation : BucketAggregationBase, IParentAggregation | ||
{ | ||
internal ParentAggregation() { } | ||
|
||
public ParentAggregation(string name, RelationName type) : base(name) => Type = type; | ||
|
||
public RelationName Type { get; set; } | ||
|
||
internal override void WrapInContainer(AggregationContainer c) => c.Parent = this; | ||
} | ||
|
||
public class ParentAggregationDescriptor<T, TParent> | ||
: BucketAggregationDescriptorBase<ParentAggregationDescriptor<T, TParent>, IParentAggregation, TParent>, IParentAggregation | ||
where T : class | ||
where TParent : class | ||
{ | ||
RelationName IParentAggregation.Type { get; set; } = typeof(T); | ||
|
||
public ParentAggregationDescriptor<T, TParent> Type(RelationName type) => | ||
Assign(a => a.Type = type); | ||
|
||
public ParentAggregationDescriptor<T, TParent> Type<TOtherParent>() => | ||
Assign(a => a.Type = typeof(TOtherParent)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
131 changes: 131 additions & 0 deletions
131
src/Tests/Tests/Aggregations/Bucket/Parent/ParentAggregationUsageTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
using Elastic.Xunit.XunitPlumbing; | ||
using Elasticsearch.Net; | ||
using FluentAssertions; | ||
using Nest; | ||
using Tests.Core.Client; | ||
using Tests.Core.Extensions; | ||
using Tests.Core.ManagedElasticsearch.Clusters; | ||
using Tests.Core.ManagedElasticsearch.NodeSeeders; | ||
using Tests.Domain; | ||
using Tests.Framework; | ||
using Tests.Framework.Integration; | ||
using static Nest.Infer; | ||
|
||
namespace Tests.Aggregations.Bucket.Parent | ||
{ | ||
/** | ||
* A special single bucket aggregation that selects parent documents that have the specified type, as defined in a `join` field. | ||
* | ||
* Be sure to read the Elasticsearch documentation on {ref_current}/search-aggregations-bucket-parent-aggregation.html[Parent Aggregation]. | ||
*/ | ||
public class ParentAggregationUsageTests : ApiIntegrationTestBase<ReadOnlyCluster, ISearchResponse<CommitActivity>, ISearchRequest, SearchDescriptor<CommitActivity>, SearchRequest<CommitActivity>> | ||
{ | ||
public ParentAggregationUsageTests(ReadOnlyCluster i, EndpointUsage usage) : base(i, usage) { } | ||
|
||
protected override bool ExpectIsValid => true; | ||
|
||
protected sealed override object ExpectJson => new | ||
{ | ||
size = 0, | ||
aggs = new | ||
{ | ||
name_of_parent_agg = new | ||
{ | ||
parent = new { type = "commits" }, | ||
aggs = new | ||
{ | ||
average_commits = new | ||
{ | ||
avg = new { field = "numberOfCommits" } | ||
}, | ||
max_commits = new | ||
{ | ||
max = new { field = "numberOfCommits" } | ||
}, | ||
min_commits = new | ||
{ | ||
min = new { field = "numberOfCommits" } | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
|
||
protected override int ExpectStatusCode => 200; | ||
|
||
// hide | ||
protected override Func<SearchDescriptor<CommitActivity>, ISearchRequest> Fluent => s => s | ||
.Size(0) | ||
.Index(DefaultSeeder.CommitsAliasFilter) | ||
.Type<CommitActivity>() | ||
.TypedKeys(TestClient.Configuration.Random.TypedKeys) | ||
.Aggregations(FluentAggs); | ||
|
||
protected override HttpMethod HttpMethod => HttpMethod.POST; | ||
|
||
// hide | ||
protected override SearchRequest<CommitActivity> Initializer => | ||
new SearchRequest<CommitActivity>(DefaultSeeder.CommitsAliasFilter, Type<CommitActivity>()) | ||
{ | ||
Size = 0, | ||
TypedKeys = TestClient.Configuration.Random.TypedKeys, | ||
Aggregations = InitializerAggs | ||
}; | ||
|
||
protected override string UrlPath => $"/commits-only/doc/_search"; | ||
|
||
// https://youtrack.jetbrains.com/issue/RIDER-19912 | ||
[U] protected override Task HitsTheCorrectUrl() => base.HitsTheCorrectUrl(); | ||
|
||
[U] protected override Task UsesCorrectHttpMethod() => base.UsesCorrectHttpMethod(); | ||
|
||
[U] protected override void SerializesInitializer() => base.SerializesInitializer(); | ||
|
||
[U] protected override void SerializesFluent() => base.SerializesFluent(); | ||
|
||
[I] public override Task ReturnsExpectedStatusCode() => base.ReturnsExpectedResponse(); | ||
|
||
[I] public override Task ReturnsExpectedIsValid() => base.ReturnsExpectedIsValid(); | ||
|
||
[I] public override Task ReturnsExpectedResponse() => base.ReturnsExpectedResponse(); | ||
|
||
protected override LazyResponses ClientUsage() => Calls( | ||
(client, f) => client.Search<CommitActivity>(f), | ||
(client, f) => client.SearchAsync<CommitActivity>(f), | ||
(client, r) => client.Search<CommitActivity>(r), | ||
(client, r) => client.SearchAsync<CommitActivity>(r) | ||
); | ||
|
||
protected Func<AggregationContainerDescriptor<CommitActivity>, IAggregationContainer> FluentAggs => a => a | ||
.Parent<Project>("name_of_parent_agg", parent => parent // <1> sub-aggregations are on the type determined from the generic type parameter. In this example, the search is against `CommitActivity` type and `Project` is a parent of `CommitActivity` | ||
.Aggregations(parentAggs => parentAggs | ||
.Average("average_commits", avg => avg.Field(p => p.NumberOfCommits)) | ||
.Max("max_commits", avg => avg.Field(p => p.NumberOfCommits)) | ||
.Min("min_commits", avg => avg.Field(p => p.NumberOfCommits)) | ||
) | ||
); | ||
|
||
protected AggregationDictionary InitializerAggs => | ||
new ParentAggregation("name_of_parent_agg", typeof(CommitActivity)) // <1> `join` field is determined from the _child_ type. In this example, it is `CommitActivity` | ||
{ | ||
Aggregations = | ||
new AverageAggregation("average_commits", Field<Project>(f => f.NumberOfCommits)) // <2> sub-aggregations are on the type determined from the `join` field. In this example, a `Project` is a parent of `CommitActivity` | ||
&& new MaxAggregation("max_commits", Field<Project>(f => f.NumberOfCommits)) | ||
&& new MinAggregation("min_commits", Field<Project>(f => f.NumberOfCommits)) | ||
}; | ||
|
||
protected override void ExpectResponse(ISearchResponse<CommitActivity> response) | ||
{ | ||
response.ShouldBeValid(); | ||
|
||
var parentAgg = response.Aggregations.Parent("name_of_parent_agg"); | ||
parentAgg.Should().NotBeNull(); | ||
parentAgg.DocCount.Should().BeGreaterThan(0); | ||
parentAgg.Min("average_commits").Should().NotBeNull(); | ||
parentAgg.Min("min_commits").Should().NotBeNull(); | ||
parentAgg.Max("max_commits").Should().NotBeNull(); | ||
} | ||
} | ||
} |