Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/aggregations.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ In addition to the buckets themselves, the bucket aggregations also compute and

* <<terms-aggregation-usage,Terms Aggregation Usage>>

* <<variable-width-histogram-usage,Variable Width Histogram Usage>>

[NOTE]
--
Bucketing aggregations can have sub-aggregations (bucketing or metric). The sub-aggregations will be computed
Expand Down Expand Up @@ -253,6 +255,8 @@ include::aggregations/bucket/significant-text/significant-text-aggregation-usage

include::aggregations/bucket/terms/terms-aggregation-usage.asciidoc[]

include::aggregations/bucket/variable-width-histogram/variable-width-histogram-usage.asciidoc[]

[[pipeline-aggregations]]
== Pipeline Aggregations

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ please modify the original csharp file found at the link and submit the PR with

A multi-bucket value source based aggregation where buckets are dynamically built - one per unique set of values.

See the Elasticsearch documentation on {ref_current}//search-aggregations-bucket-multi-terms-aggregation.html[multi terms aggregation] for more detail.
See the Elasticsearch documentation on {ref_current}/search-aggregations-bucket-multi-terms-aggregation.html[multi terms aggregation] for more detail.

==== Fluent DSL example

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
:ref_current: https://www.elastic.co/guide/en/elasticsearch/reference/7.x

: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/7.x/src/Tests/Tests/Aggregations/Bucket/VariableWidthHistogram/VariableWidthHistogramUsageTests.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!
////

[[variable-width-histogram-usage]]
=== Variable Width Histogram Usage

A multi-bucket aggregation similar to Histogram. However, the width of each bucket is not specified. Rather, a target number of buckets is provided
and bucket intervals are dynamically determined based on the document distribution.

See the Elasticsearch documentation on {ref_current}/search-aggregations-bucket-variablewidthhistogram-aggregation.html[multi terms aggregation] for more detail.

==== Fluent DSL example

[source,csharp]
----
a => a
.VariableWidthHistogram("commits", v => v
.Field(f => f.NumberOfCommits)
.Buckets(2)
.InitialBuffer(2)
.ShardSize(100)
.Meta(m => m
.Add("foo", "bar")
))
----

==== Object Initializer syntax example

[source,csharp]
----
new VariableWidthHistogramAggregation("commits")
{
Field = Field<Project>(f => f.NumberOfCommits),
Buckets = 2,
InitialBuffer = 2,
ShardSize = 100,
Meta = new Dictionary<string, object>
{
{ "foo", "bar" }
}
}
----

[source,javascript]
.Example json output
----
{
"commits": {
"meta": {
"foo": "bar"
},
"variable_width_histogram": {
"field": "numberOfCommits",
"buckets": 2,
"initial_buffer": 2,
"shard_size": 100
}
}
}
----

==== Handling Responses

[source,csharp]
----
response.ShouldBeValid();
var counts = response.Aggregations.VariableWidthHistogram("commits");
counts.Should().NotBeNull();
counts.Buckets.Should().HaveCountGreaterThan(0);
var firstBucket = counts.Buckets.First();
firstBucket.Key.Should().BeGreaterOrEqualTo(0);
firstBucket.Minimum.Should().BeGreaterOrEqualTo(0);
firstBucket.Maximum.Should().BeGreaterOrEqualTo(0);
firstBucket.DocCount.Should().BeGreaterOrEqualTo(1);
counts.Meta.Should().NotBeNull().And.HaveCount(1);
counts.Meta["foo"].Should().Be("bar");
----

2 changes: 2 additions & 0 deletions src/Nest/Aggregations/AggregateDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ public MultiBucketAggregate<RareTermsBucket<TKey>> RareTerms<TKey>(string key)

public MultiBucketAggregate<DateHistogramBucket> DateHistogram(string key) => GetMultiBucketAggregate<DateHistogramBucket>(key);

public MultiBucketAggregate<VariableWidthHistogramBucket> VariableWidthHistogram(string key) => GetMultiBucketAggregate<VariableWidthHistogramBucket>(key);

public MultiTermsAggregate<string> MultiTerms(string key) => MultiTerms<string>(key);

public MultiTermsAggregate<TKey> MultiTerms<TKey>(string key)
Expand Down
43 changes: 41 additions & 2 deletions src/Nest/Aggregations/AggregateFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ internal class AggregateFormatter : IJsonFormatter<IAggregate>
{ Parser.From, 1 },
{ Parser.To, 2 },
{ Parser.KeyAsString, 3 },
{ Parser.DocCount, 4 }
{ Parser.DocCount, 4 },
{ Parser.Min, 5 }
};

private static readonly byte[] BucketsField = JsonWriter.GetEncodedPropertyNameWithoutQuotation(Parser.Buckets);
Expand Down Expand Up @@ -219,6 +220,9 @@ private IBucket ReadBucket(ref JsonReader reader, IJsonFormatterResolver formatt
case 4:
item = GetFiltersBucket(ref reader, formatterResolver);
break;
case 5:
item = GetVariableWidthHistogramBucket(ref reader, formatterResolver);
break;
}
}
else
Expand Down Expand Up @@ -939,7 +943,42 @@ private IBucket GetDateHistogramBucket(ref JsonReader reader, IJsonFormatterReso

return dateHistogram;
}


private IBucket GetVariableWidthHistogramBucket(ref JsonReader reader, IJsonFormatterResolver formatterResolver)
{
var min = reader.ReadDouble();
reader.ReadNext(); // ,
reader.ReadNext(); // "key"
reader.ReadNext(); // :
var key = reader.ReadDouble();
reader.ReadNext(); // ,
reader.ReadNext(); // "max"
reader.ReadNext(); // :
var max = reader.ReadDouble();
reader.ReadNext(); // ,
reader.ReadNext(); // "doc_count"
reader.ReadNext(); // :
var docCount = reader.ReadInt64();

Dictionary<string, IAggregate> subAggregates = null;
if (reader.GetCurrentJsonToken() == JsonToken.ValueSeparator)
{
reader.ReadNext(); // ,
var propertyName = reader.ReadPropertyName();
subAggregates = GetSubAggregates(ref reader, propertyName, formatterResolver);
}

var variableWidthHistogram = new VariableWidthHistogramBucket(subAggregates)
{
Key = key,
Minimum = min,
Maximum = max,
DocCount = docCount,
};

return variableWidthHistogram;
}

private IBucket GetKeyedBucket(ref JsonReader reader, IJsonFormatterResolver formatterResolver)
{
var token = reader.GetCurrentJsonToken();
Expand Down
12 changes: 12 additions & 0 deletions src/Nest/Aggregations/AggregationContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,9 @@ public interface IAggregationContainer

[DataMember(Name = "multi_terms")]
IMultiTermsAggregation MultiTerms { get; set; }

[DataMember(Name = "variable_width_histogram")]
IVariableWidthHistogramAggregation VariableWidthHistogram { get; set; }

void Accept(IAggregationVisitor visitor);
}
Expand Down Expand Up @@ -446,6 +449,8 @@ public class AggregationContainer : IAggregationContainer

public IMultiTermsAggregation MultiTerms { get; set; }

public IVariableWidthHistogramAggregation VariableWidthHistogram { get; set; }

public void Accept(IAggregationVisitor visitor)
{
if (visitor.Scope == AggregationVisitorScope.Unknown) visitor.Scope = AggregationVisitorScope.Aggregation;
Expand Down Expand Up @@ -615,6 +620,8 @@ public class AggregationContainerDescriptor<T> : DescriptorBase<AggregationConta

ITopMetricsAggregation IAggregationContainer.TopMetrics { get; set; }

IVariableWidthHistogramAggregation IAggregationContainer.VariableWidthHistogram { get; set; }

public void Accept(IAggregationVisitor visitor)
{
if (visitor.Scope == AggregationVisitorScope.Unknown) visitor.Scope = AggregationVisitorScope.Aggregation;
Expand Down Expand Up @@ -960,6 +967,11 @@ Func<TopMetricsAggregationDescriptor<T>, ITopMetricsAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.TopMetrics = d);

public AggregationContainerDescriptor<T> VariableWidthHistogram(string name,
Func<VariableWidthHistogramAggregationDescriptor<T>, IVariableWidthHistogramAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.VariableWidthHistogram = d);

/// <summary>
/// Fluent methods do not assign to properties on `this` directly but on IAggregationContainers inside
/// `this.Aggregations[string, IContainer]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using System;
using System.Linq.Expressions;
using System.Runtime.Serialization;
using Elasticsearch.Net.Utf8Json;

namespace Nest
{
[InterfaceDataContract]
[ReadAs(typeof(VariableWidthHistogramAggregation))]
public interface IVariableWidthHistogramAggregation : IBucketAggregation
{
/// <summary>
/// The field to target.
/// </summary>
[DataMember(Name = "field")]
Field Field { get; set; }

[DataMember(Name = "buckets")]
int? Buckets { get; set; }

[DataMember(Name = "initial_buffer")]
int? InitialBuffer { get; set; }

[DataMember(Name = "shard_size")]
int? ShardSize { get; set; }
}

public class VariableWidthHistogramAggregation : BucketAggregationBase, IVariableWidthHistogramAggregation
{
public VariableWidthHistogramAggregation(string name) : base(name) { }

/// <inheritdoc />
public Field Field { get; set; }
/// <inheritdoc />
public int? Buckets { get; set; }
/// <inheritdoc />
public int? InitialBuffer { get; set; }
/// <inheritdoc />
public int? ShardSize { get; set; }

internal override void WrapInContainer(AggregationContainer c) => c.VariableWidthHistogram = this;
}

public class VariableWidthHistogramAggregationDescriptor<T>
: BucketAggregationDescriptorBase<VariableWidthHistogramAggregationDescriptor<T>, IVariableWidthHistogramAggregation, T>, IVariableWidthHistogramAggregation
where T : class
{
Field IVariableWidthHistogramAggregation.Field { get; set; }
int? IVariableWidthHistogramAggregation.Buckets { get; set; }
int? IVariableWidthHistogramAggregation.InitialBuffer { get; set; }
int? IVariableWidthHistogramAggregation.ShardSize { get; set; }

/// <inheritdoc cref="IVariableWidthHistogramAggregation.Field" />
public VariableWidthHistogramAggregationDescriptor<T> Field(Field field) => Assign(field, (a, v) => a.Field = v);

/// <inheritdoc cref="IVariableWidthHistogramAggregation.Field" />
public VariableWidthHistogramAggregationDescriptor<T> Field<TValue>(Expression<Func<T, TValue>> field) => Assign(field, (a, v) => a.Field = v);

/// <inheritdoc cref="IVariableWidthHistogramAggregation.Buckets" />
public VariableWidthHistogramAggregationDescriptor<T> Buckets(int? buckets) => Assign(buckets, (a, v) => a.Buckets = v);

/// <inheritdoc cref="IVariableWidthHistogramAggregation.InitialBuffer" />
public VariableWidthHistogramAggregationDescriptor<T> InitialBuffer(int? initialBuffer) => Assign(initialBuffer, (a, v) => a.InitialBuffer = v);

/// <inheritdoc cref="IVariableWidthHistogramAggregation.ShardSize" />
public VariableWidthHistogramAggregationDescriptor<T> ShardSize(int? shardSize) => Assign(shardSize, (a, v) => a.ShardSize = v);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information

using System.Collections.Generic;

namespace Nest
{
public class VariableWidthHistogramBucket : BucketBase
{
public VariableWidthHistogramBucket(IReadOnlyDictionary<string, IAggregate> dict) : base(dict) { }

public double Key { get; set; }

public double Minimum { get; set; }

public double Maximum { get; set; }

public long DocCount { get; set; }
}
}
4 changes: 4 additions & 0 deletions src/Nest/Aggregations/Visitor/AggregationVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ public interface IAggregationVisitor
void Visit(ITTestAggregation aggregation);

void Visit(IMultiTermsAggregation aggregation);

void Visit(IVariableWidthHistogramAggregation aggregation);
}

public class AggregationVisitor : IAggregationVisitor
Expand Down Expand Up @@ -307,5 +309,7 @@ public virtual void Visit(IAggregation aggregation) { }

public virtual void Visit(IAggregationContainer aggregationContainer) { }

public virtual void Visit(IVariableWidthHistogramAggregation aggregationContainer) { }

}
}
5 changes: 5 additions & 0 deletions src/Nest/Aggregations/Visitor/AggregationWalker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,11 @@ public void Walk(IAggregationContainer aggregation, IAggregationVisitor visitor)
AcceptAggregation(aggregation.Composite, visitor, (v, d) => v.Visit(d));
AcceptAggregation(aggregation.MedianAbsoluteDeviation, visitor, (v, d) => v.Visit(d));
AcceptAggregation(aggregation.TTest, visitor, (v, d) => v.Visit(d));
AcceptAggregation(aggregation.VariableWidthHistogram, visitor, (v, d) =>
{
v.Visit(d);
Accept(v, d.Aggregations);
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace Tests.Aggregations.Bucket.MultiTerms
/**
* A multi-bucket value source based aggregation where buckets are dynamically built - one per unique set of values.
*
* See the Elasticsearch documentation on {ref_current}//search-aggregations-bucket-multi-terms-aggregation.html[multi terms aggregation] for more detail.
* See the Elasticsearch documentation on {ref_current}/search-aggregations-bucket-multi-terms-aggregation.html[multi terms aggregation] for more detail.
*/
[SkipVersion("<7.12.0", "Multi terms aggregation added in 7.12.0")]
public class MultiTermsAggregationUsageTests : AggregationUsageTestBase<ReadOnlyCluster>
Expand Down
Loading