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
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Be sure to read the Elasticsearch documentation on {ref_current}/search-aggregat
a => a
.DateHistogram("projects_started_per_month", date => date
.Field(p => p.StartedOn)
.Interval(DateInterval.Month)
.CalendarInterval(DateInterval.Month)
.MinimumDocumentCount(2)
.Format("yyyy-MM-dd'T'HH:mm:ss")
.ExtendedBounds(FixedDate.AddYears(-1), FixedDate.AddYears(1))
Expand All @@ -56,7 +56,7 @@ a => a
new DateHistogramAggregation("projects_started_per_month")
{
Field = Field<Project>(p => p.StartedOn),
Interval = DateInterval.Month,
CalendarInterval = DateInterval.Month,
MinimumDocumentCount = 2,
Format = "yyyy-MM-dd'T'HH:mm:ss",
ExtendedBounds = new ExtendedBounds<DateMath>
Expand Down Expand Up @@ -84,7 +84,7 @@ new DateHistogramAggregation("projects_started_per_month")
"projects_started_per_month": {
"date_histogram": {
"field": "startedOn",
"interval": "month",
"calendar_interval": "month",
"min_doc_count": 2,
"format": "yyyy-MM-dd'T'HH:mm:ss||date_optional_time",
"order": {
Expand Down
100 changes: 78 additions & 22 deletions src/Nest/Aggregations/Bucket/DateHistogram/DateHistogramAggregation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,43 +14,81 @@ namespace Nest
[ReadAs(typeof(DateHistogramAggregation))]
public interface IDateHistogramAggregation : IBucketAggregation
{
/// <summary>
/// Extend the bounds of the date histogram beyond the data itself,
/// forcing the aggregation to start building buckets on
/// a specific min and/or max value.
/// Using extended bounds only makes sense when <see cref="MinimumDocumentCount"/> is 0
/// as empty buckets will never be returned if it is greater than 0.
/// </summary>
[DataMember(Name ="extended_bounds")]
ExtendedBounds<DateMath> ExtendedBounds { get; set; }

/// <summary>
/// The field to target
/// </summary>
[DataMember(Name ="field")]
Field Field { get; set; }

/// <summary>
/// Return a formatted date string as the key instead an epoch long
/// </summary>
[DataMember(Name ="format")]
string Format { get; set; }

[Obsolete("Deprecated in version 7.2.0, use CalendarInterval or FixedInterval instead")]
[DataMember(Name ="interval")]
Union<DateInterval, Time> Interval { get; set; }

/// <summary>
/// The calendar interval to use when bucketing documents
/// </summary>
[DataMember(Name ="calendar_interval")]
Union<DateInterval, Time> CalendarInterval { get; set; }
Union<DateInterval?, DateMathTime> CalendarInterval { get; set; }

/// <summary>
/// The fixed interval to use when bucketing documents
/// </summary>
[DataMember(Name ="fixed_interval")]
Union<DateInterval, Time> FixedInterval { get; set; }
Time FixedInterval { get; set; }

/// <summary>
/// The minimum number of documents that a bucket must contain to be returned in the response.
/// The default is 0 meaning that buckets with no documents will be returned.
/// </summary>
[DataMember(Name ="min_doc_count")]
int? MinimumDocumentCount { get; set; }

/// <summary>
/// Defines how to treat documents that are missing a value. By default, they are ignored,
/// but it is also possible to treat them as if they have a value.
/// </summary>
[DataMember(Name ="missing")]
DateTime? Missing { get; set; }

/// <summary>
/// Change the start value of each bucket by the specified positive (+) or negative offset (-) duration,
/// such as 1h for an hour, or 1d for a day.
/// </summary>
[DataMember(Name ="offset")]
string Offset { get; set; }

/// <summary>
/// Defines an order in which returned buckets are sorted.
/// By default the returned buckets are sorted by their key ascending.
/// </summary>
[DataMember(Name ="order")]
HistogramOrder Order { get; set; }

[DataMember(Name ="params")]
IDictionary<string, object> Params { get; set; }

/// <inheritdoc cref="IScript"/>
[DataMember(Name ="script")]
IScript Script { get; set; }

/// <summary>
/// Used to indicate that bucketing should use a different time zone.
/// Time zones may either be specified as an ISO 8601 UTC offset (e.g. +01:00 or -08:00)
/// or as a timezone id, an identifier used in the TZ database like America/Los_Angeles.
/// </summary>
[DataMember(Name ="time_zone")]
string TimeZone { get; set; }
}
Expand All @@ -63,9 +101,12 @@ internal DateHistogramAggregation() { }

public DateHistogramAggregation(string name) : base(name) { }

/// <inheritdoc />
public ExtendedBounds<DateMath> ExtendedBounds { get; set; }
/// <inheritdoc />
public Field Field { get; set; }

/// <inheritdoc />
public string Format
{
get => !string.IsNullOrEmpty(_format) &&
Expand All @@ -79,15 +120,21 @@ public string Format

[Obsolete("Deprecated in version 7.2.0, use CalendarInterval or FixedInterval instead")]
public Union<DateInterval, Time> Interval { get; set; }
public Union<DateInterval, Time> CalendarInterval { get; set; }
public Union<DateInterval, Time> FixedInterval { get; set; }

/// <inheritdoc />
public Union<DateInterval?, DateMathTime> CalendarInterval { get; set; }
/// <inheritdoc />
public Time FixedInterval { get; set; }
/// <inheritdoc />
public int? MinimumDocumentCount { get; set; }
/// <inheritdoc />
public DateTime? Missing { get; set; }
/// <inheritdoc />
public string Offset { get; set; }
/// <inheritdoc />
public HistogramOrder Order { get; set; }
public IDictionary<string, object> Params { get; set; }
/// <inheritdoc />
public IScript Script { get; set; }
/// <inheritdoc />
public string TimeZone { get; set; }

internal override void WrapInContainer(AggregationContainer c) => c.DateHistogram = this;
Expand Down Expand Up @@ -116,29 +163,25 @@ string IDateHistogramAggregation.Format

[Obsolete("Deprecated in version 7.2.0, use CalendarInterval or FixedInterval instead")]
Union<DateInterval, Time> IDateHistogramAggregation.Interval { get; set; }
Union<DateInterval, Time> IDateHistogramAggregation.CalendarInterval { get; set; }
Union<DateInterval, Time> IDateHistogramAggregation.FixedInterval { get; set; }

Union<DateInterval?, DateMathTime> IDateHistogramAggregation.CalendarInterval { get; set; }
Time IDateHistogramAggregation.FixedInterval { get; set; }
int? IDateHistogramAggregation.MinimumDocumentCount { get; set; }

DateTime? IDateHistogramAggregation.Missing { get; set; }

string IDateHistogramAggregation.Offset { get; set; }

HistogramOrder IDateHistogramAggregation.Order { get; set; }

IDictionary<string, object> IDateHistogramAggregation.Params { get; set; }

IScript IDateHistogramAggregation.Script { get; set; }

string IDateHistogramAggregation.TimeZone { get; set; }

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

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

/// <inheritdoc cref="IDateHistogramAggregation.Script" />
public DateHistogramAggregationDescriptor<T> Script(string script) => Assign((InlineScript)script, (a, v) => a.Script = v);

/// <inheritdoc cref="IDateHistogramAggregation.Script" />
public DateHistogramAggregationDescriptor<T> Script(Func<ScriptDescriptor, IScript> scriptSelector) =>
Assign(scriptSelector, (a, v) => a.Script = v?.Invoke(new ScriptDescriptor()));

Expand All @@ -149,31 +192,44 @@ public DateHistogramAggregationDescriptor<T> Script(Func<ScriptDescriptor, IScri
public DateHistogramAggregationDescriptor<T> Interval(DateInterval interval) =>
Assign(interval, (a, v) => a.Interval = v);

public DateHistogramAggregationDescriptor<T> CalendarInterval(Time interval) => Assign(interval, (a, v) => a.CalendarInterval = v);
public DateHistogramAggregationDescriptor<T> CalendarInterval(DateInterval interval) => Assign(interval, (a, v) => a.CalendarInterval = v);
/// <inheritdoc cref="IDateHistogramAggregation.CalendarInterval" />
public DateHistogramAggregationDescriptor<T> CalendarInterval(DateMathTime interval) => Assign(interval, (a, v) => a.CalendarInterval = v);

/// <inheritdoc cref="IDateHistogramAggregation.CalendarInterval" />
public DateHistogramAggregationDescriptor<T> CalendarInterval(DateInterval? interval) => Assign(interval, (a, v) => a.CalendarInterval = v);

/// <inheritdoc cref="IDateHistogramAggregation.FixedInterval" />
public DateHistogramAggregationDescriptor<T> FixedInterval(Time interval) => Assign(interval, (a, v) => a.FixedInterval = v);
public DateHistogramAggregationDescriptor<T> FixedInterval(DateInterval interval) => Assign(interval, (a, v) => a.FixedInterval = v);

/// <inheritdoc cref="IDateHistogramAggregation.Format" />
public DateHistogramAggregationDescriptor<T> Format(string format) => Assign(format, (a, v) => a.Format = v);

/// <inheritdoc cref="IDateHistogramAggregation.MinimumDocumentCount" />
public DateHistogramAggregationDescriptor<T> MinimumDocumentCount(int? minimumDocumentCount) =>
Assign(minimumDocumentCount, (a, v) => a.MinimumDocumentCount = v);

/// <inheritdoc cref="IDateHistogramAggregation.TimeZone" />
public DateHistogramAggregationDescriptor<T> TimeZone(string timeZone) => Assign(timeZone, (a, v) => a.TimeZone = v);

/// <inheritdoc cref="IDateHistogramAggregation.Offset" />
public DateHistogramAggregationDescriptor<T> Offset(string offset) => Assign(offset, (a, v) => a.Offset = v);

/// <inheritdoc cref="IDateHistogramAggregation.Order" />
public DateHistogramAggregationDescriptor<T> Order(HistogramOrder order) => Assign(order, (a, v) => a.Order = v);

/// <inheritdoc cref="IDateHistogramAggregation.Order" />
public DateHistogramAggregationDescriptor<T> OrderAscending(string key) =>
Assign(new HistogramOrder { Key = key, Order = SortOrder.Descending }, (a, v) => a.Order = v);

/// <inheritdoc cref="IDateHistogramAggregation.Order" />
public DateHistogramAggregationDescriptor<T> OrderDescending(string key) =>
Assign(new HistogramOrder { Key = key, Order = SortOrder.Descending }, (a, v) => a.Order = v);

/// <inheritdoc cref="IDateHistogramAggregation.ExtendedBounds" />
public DateHistogramAggregationDescriptor<T> ExtendedBounds(DateMath min, DateMath max) =>
Assign(new ExtendedBounds<DateMath> { Minimum = min, Maximum = max }, (a, v) => a.ExtendedBounds = v);

/// <inheritdoc cref="IDateHistogramAggregation.Missing" />
public DateHistogramAggregationDescriptor<T> Missing(DateTime? missing) => Assign(missing, (a, v) => a.Missing = v);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public DateHistogramAggregationUsageTests(ReadOnlyCluster i, EndpointUsage usage
date_histogram = new
{
field = "startedOn",
interval = "month",
calendar_interval = "month",
min_doc_count = 2,
format = "yyyy-MM-dd'T'HH:mm:ss||date_optional_time", //<1> Note the inclusion of `date_optional_time` to `format`
order = new { _count = "asc" },
Expand Down Expand Up @@ -72,7 +72,7 @@ public DateHistogramAggregationUsageTests(ReadOnlyCluster i, EndpointUsage usage
protected override Func<AggregationContainerDescriptor<Project>, IAggregationContainer> FluentAggs => a => a
.DateHistogram("projects_started_per_month", date => date
.Field(p => p.StartedOn)
.Interval(DateInterval.Month)
.CalendarInterval(DateInterval.Month)
.MinimumDocumentCount(2)
.Format("yyyy-MM-dd'T'HH:mm:ss")
.ExtendedBounds(FixedDate.AddYears(-1), FixedDate.AddYears(1))
Expand All @@ -92,7 +92,7 @@ public DateHistogramAggregationUsageTests(ReadOnlyCluster i, EndpointUsage usage
new DateHistogramAggregation("projects_started_per_month")
{
Field = Field<Project>(p => p.StartedOn),
Interval = DateInterval.Month,
CalendarInterval = DateInterval.Month,
MinimumDocumentCount = 2,
Format = "yyyy-MM-dd'T'HH:mm:ss",
ExtendedBounds = new ExtendedBounds<DateMath>
Expand Down Expand Up @@ -147,12 +147,12 @@ public DateHistogramAggregationNoSubAggregationsUsageTests(ReadOnlyCluster i, En

protected override object AggregationJson => new
{
projects_started_per_month = new
projects_started_per_four_weeks = new
{
date_histogram = new
{
field = "startedOn",
interval = "month",
fixed_interval = "28d",
min_doc_count = 2,
format = "yyyy-MM-dd'T'HH:mm:ss||date_optional_time",
order = new { _count = "asc" },
Expand All @@ -168,9 +168,9 @@ public DateHistogramAggregationNoSubAggregationsUsageTests(ReadOnlyCluster i, En

#pragma warning disable 618, 612
protected override Func<AggregationContainerDescriptor<Project>, IAggregationContainer> FluentAggs => a => a
.DateHistogram("projects_started_per_month", date => date
.DateHistogram("projects_started_per_four_weeks", date => date
.Field(p => p.StartedOn)
.Interval(DateInterval.Month)
.FixedInterval(new Time(28, TimeUnit.Day))
.MinimumDocumentCount(2)
.Format("yyyy-MM-dd'T'HH:mm:ss")
.ExtendedBounds(FixedDate.AddYears(-1), FixedDate.AddYears(1))
Expand All @@ -179,10 +179,10 @@ public DateHistogramAggregationNoSubAggregationsUsageTests(ReadOnlyCluster i, En
);

protected override AggregationDictionary InitializerAggs =>
new DateHistogramAggregation("projects_started_per_month")
new DateHistogramAggregation("projects_started_per_four_weeks")
{
Field = Field<Project>(p => p.StartedOn),
Interval = DateInterval.Month,
FixedInterval = new Time(28, TimeUnit.Day),
MinimumDocumentCount = 2,
Format = "yyyy-MM-dd'T'HH:mm:ss",
ExtendedBounds = new ExtendedBounds<DateMath>
Expand All @@ -198,7 +198,7 @@ public DateHistogramAggregationNoSubAggregationsUsageTests(ReadOnlyCluster i, En
protected override void ExpectResponse(ISearchResponse<Project> response)
{
response.ShouldBeValid();
var dateHistogram = response.Aggregations.DateHistogram("projects_started_per_month");
var dateHistogram = response.Aggregations.DateHistogram("projects_started_per_four_weeks");
dateHistogram.Should().NotBeNull();
dateHistogram.Buckets.Should().NotBeNull();
dateHistogram.Buckets.Count.Should().BeGreaterThan(10);
Expand Down