/* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/
/*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using OpenSearch.Net.Utf8Json;
namespace OpenSearch.Client
{
///
/// Describes aggregations that we would like to execute on OpenSearch.
///
/// In OSC Aggregation always refers to an aggregation
/// sent to OpenSearch and an Aggregate describes an aggregation returned from OpenSearch.
///
[JsonFormatter(typeof(AggregationDictionaryFormatter))]
public class AggregationDictionary : IsADictionaryBase
{
public AggregationDictionary() { }
public AggregationDictionary(IDictionary container) : base(container) { }
public AggregationDictionary(Dictionary container)
: base(container.ToDictionary(kv => kv.Key, kv => (IAggregationContainer)kv.Value)) { }
public static implicit operator AggregationDictionary(Dictionary container) =>
new AggregationDictionary(container);
public static implicit operator AggregationDictionary(Dictionary container) =>
new AggregationDictionary(container);
public static implicit operator AggregationDictionary(AggregationBase aggregator)
{
IAggregation b;
if (aggregator is AggregationCombinator combinator)
{
var dict = new AggregationDictionary();
foreach (var agg in combinator.Aggregations)
{
b = agg;
if (b.Name.IsNullOrEmpty())
throw new ArgumentException($"{aggregator.GetType().Name} .Name is not set!");
dict.Add(b.Name, agg);
}
return dict;
}
b = aggregator;
if (b.Name.IsNullOrEmpty())
throw new ArgumentException($"{aggregator.GetType().Name} .Name is not set!");
return new AggregationDictionary { { b.Name, aggregator } };
}
public void Add(string key, AggregationContainer value) => BackingDictionary.Add(ValidateKey(key), value);
protected override string ValidateKey(string key)
{
if (AggregateFormatter.AllReservedAggregationNames.Contains(key))
throw new ArgumentException(
string.Format(AggregateFormatter.UsingReservedAggNameFormat, key), nameof(key));
return key;
}
}
internal class AggregationDictionaryFormatter : IJsonFormatter
{
private static readonly VerbatimDictionaryInterfaceKeysFormatter DictionaryKeysFormatter =
new VerbatimDictionaryInterfaceKeysFormatter();
public AggregationDictionary Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver) =>
new AggregationDictionary(DictionaryKeysFormatter.Deserialize(ref reader, formatterResolver));
public void Serialize(ref JsonWriter writer, AggregationDictionary value, IJsonFormatterResolver formatterResolver) =>
DictionaryKeysFormatter.Serialize(ref writer, value, formatterResolver);
}
[InterfaceDataContract]
[ReadAs(typeof(AggregationContainer))]
public interface IAggregationContainer
{
[DataMember(Name = "adjacency_matrix")]
IAdjacencyMatrixAggregation AdjacencyMatrix { get; set; }
[DataMember(Name = "aggs")]
AggregationDictionary Aggregations { get; set; }
[DataMember(Name = "avg")]
IAverageAggregation Average { get; set; }
[DataMember(Name = "avg_bucket")]
IAverageBucketAggregation AverageBucket { get; set; }
[DataMember(Name = "bucket_script")]
IBucketScriptAggregation BucketScript { get; set; }
[DataMember(Name = "bucket_selector")]
IBucketSelectorAggregation BucketSelector { get; set; }
[DataMember(Name = "bucket_sort")]
IBucketSortAggregation BucketSort { get; set; }
[DataMember(Name = "cardinality")]
ICardinalityAggregation Cardinality { get; set; }
[DataMember(Name = "children")]
IChildrenAggregation Children { get; set; }
[DataMember(Name = "composite")]
ICompositeAggregation Composite { get; set; }
[DataMember(Name = "cumulative_sum")]
ICumulativeSumAggregation CumulativeSum { get; set; }
[DataMember(Name = "date_histogram")]
IDateHistogramAggregation DateHistogram { get; set; }
[DataMember(Name ="auto_date_histogram")]
IAutoDateHistogramAggregation AutoDateHistogram { get; set; }
[DataMember(Name = "date_range")]
IDateRangeAggregation DateRange { get; set; }
[DataMember(Name = "derivative")]
IDerivativeAggregation Derivative { get; set; }
[DataMember(Name = "diversified_sampler")]
IDiversifiedSamplerAggregation DiversifiedSampler { get; set; }
[DataMember(Name = "extended_stats")]
IExtendedStatsAggregation ExtendedStats { get; set; }
[DataMember(Name = "extended_stats_bucket")]
IExtendedStatsBucketAggregation ExtendedStatsBucket { get; set; }
[DataMember(Name = "filter")]
IFilterAggregation Filter { get; set; }
[DataMember(Name = "filters")]
IFiltersAggregation Filters { get; set; }
[DataMember(Name = "geo_bounds")]
IGeoBoundsAggregation GeoBounds { get; set; }
[DataMember(Name = "geo_centroid")]
IGeoCentroidAggregation GeoCentroid { get; set; }
[DataMember(Name = "geo_distance")]
IGeoDistanceAggregation GeoDistance { get; set; }
[DataMember(Name = "geohash_grid")]
IGeoHashGridAggregation GeoHash { get; set; }
[DataMember(Name = "geo_line")]
IGeoLineAggregation GeoLine { get; set; }
[DataMember(Name = "geotile_grid")]
IGeoTileGridAggregation GeoTile { get; set; }
[DataMember(Name = "global")]
IGlobalAggregation Global { get; set; }
[DataMember(Name = "histogram")]
IHistogramAggregation Histogram { get; set; }
[DataMember(Name = "ip_range")]
IIpRangeAggregation IpRange { get; set; }
[DataMember(Name = "matrix_stats")]
IMatrixStatsAggregation MatrixStats { get; set; }
[DataMember(Name = "max")]
IMaxAggregation Max { get; set; }
[DataMember(Name = "max_bucket")]
IMaxBucketAggregation MaxBucket { get; set; }
[DataMember(Name = "meta")]
[JsonFormatter(typeof(VerbatimDictionaryInterfaceKeysFormatter))]
IDictionary Meta { get; set; }
[DataMember(Name = "min")]
IMinAggregation Min { get; set; }
[DataMember(Name = "min_bucket")]
IMinBucketAggregation MinBucket { get; set; }
[DataMember(Name = "missing")]
IMissingAggregation Missing { get; set; }
[DataMember(Name = "moving_avg")]
IMovingAverageAggregation MovingAverage { get; set; }
[DataMember(Name = "moving_fn")]
IMovingFunctionAggregation MovingFunction { get; set; }
[DataMember(Name = "nested")]
INestedAggregation Nested { get; set; }
///
[DataMember(Name = "parent")]
IParentAggregation Parent { get; set; }
[DataMember(Name = "percentile_ranks")]
IPercentileRanksAggregation PercentileRanks { get; set; }
[DataMember(Name = "percentiles")]
IPercentilesAggregation Percentiles { get; set; }
[DataMember(Name = "percentiles_bucket")]
IPercentilesBucketAggregation PercentilesBucket { get; set; }
[DataMember(Name = "range")]
IRangeAggregation Range { get; set; }
[DataMember(Name = "rare_terms")]
IRareTermsAggregation RareTerms { get; set; }
[DataMember(Name = "reverse_nested")]
IReverseNestedAggregation ReverseNested { get; set; }
[DataMember(Name = "sampler")]
ISamplerAggregation Sampler { get; set; }
[DataMember(Name = "scripted_metric")]
IScriptedMetricAggregation ScriptedMetric { get; set; }
[DataMember(Name = "serial_diff")]
ISerialDifferencingAggregation SerialDifferencing { get; set; }
[DataMember(Name = "significant_terms")]
ISignificantTermsAggregation SignificantTerms { get; set; }
[DataMember(Name = "significant_text")]
ISignificantTextAggregation SignificantText { get; set; }
[DataMember(Name = "stats")]
IStatsAggregation Stats { get; set; }
[DataMember(Name = "stats_bucket")]
IStatsBucketAggregation StatsBucket { get; set; }
[DataMember(Name = "sum")]
ISumAggregation Sum { get; set; }
[DataMember(Name = "sum_bucket")]
ISumBucketAggregation SumBucket { get; set; }
[DataMember(Name = "terms")]
ITermsAggregation Terms { get; set; }
[DataMember(Name = "top_hits")]
ITopHitsAggregation TopHits { get; set; }
[DataMember(Name = "value_count")]
IValueCountAggregation ValueCount { get; set; }
[DataMember(Name = "weighted_avg")]
IWeightedAverageAggregation WeightedAverage { get; set; }
[DataMember(Name = "median_absolute_deviation")]
IMedianAbsoluteDeviationAggregation MedianAbsoluteDeviation { get; set; }
[DataMember(Name = "multi_terms")]
IMultiTermsAggregation MultiTerms { get; set; }
[DataMember(Name = "variable_width_histogram")]
IVariableWidthHistogramAggregation VariableWidthHistogram { get; set; }
void Accept(IAggregationVisitor visitor);
}
public class AggregationContainer : IAggregationContainer
{
public IAdjacencyMatrixAggregation AdjacencyMatrix { get; set; }
// This is currently used to support deserializing the response from SQL Translate,
// which forms a response which uses "aggregations", rather than "aggs". Longer term
// it would be preferred to address that in OpenSearch itself.
[DataMember(Name = "aggregations")]
private AggregationDictionary _aggs;
// ReSharper disable once ConvertToAutoProperty
public AggregationDictionary Aggregations { get => _aggs; set => _aggs = value; }
public IAverageAggregation Average { get; set; }
public IAverageBucketAggregation AverageBucket { get; set; }
public IBucketScriptAggregation BucketScript { get; set; }
public IBucketSelectorAggregation BucketSelector { get; set; }
public IBucketSortAggregation BucketSort { get; set; }
public ICardinalityAggregation Cardinality { get; set; }
public IChildrenAggregation Children { get; set; }
public ICompositeAggregation Composite { get; set; }
public ICumulativeSumAggregation CumulativeSum { get; set; }
public IDateHistogramAggregation DateHistogram { get; set; }
public IAutoDateHistogramAggregation AutoDateHistogram { get; set; }
public IDateRangeAggregation DateRange { get; set; }
public IDerivativeAggregation Derivative { get; set; }
public IDiversifiedSamplerAggregation DiversifiedSampler { get; set; }
public IExtendedStatsAggregation ExtendedStats { get; set; }
public IExtendedStatsBucketAggregation ExtendedStatsBucket { get; set; }
public IFilterAggregation Filter { get; set; }
public IFiltersAggregation Filters { get; set; }
public IGeoBoundsAggregation GeoBounds { get; set; }
public IGeoCentroidAggregation GeoCentroid { get; set; }
public IGeoDistanceAggregation GeoDistance { get; set; }
public IGeoHashGridAggregation GeoHash { get; set; }
public IGeoLineAggregation GeoLine { get; set; }
public IGeoTileGridAggregation GeoTile { get; set; }
public IGlobalAggregation Global { get; set; }
public IHistogramAggregation Histogram { get; set; }
public IIpRangeAggregation IpRange { get; set; }
public IMatrixStatsAggregation MatrixStats { get; set; }
public IMaxAggregation Max { get; set; }
public IMaxBucketAggregation MaxBucket { get; set; }
public IDictionary Meta { get; set; }
public IMinAggregation Min { get; set; }
public IMinBucketAggregation MinBucket { get; set; }
public IMissingAggregation Missing { get; set; }
public IMovingAverageAggregation MovingAverage { get; set; }
public IMovingFunctionAggregation MovingFunction { get; set; }
public INestedAggregation Nested { get; set; }
///
public IParentAggregation Parent { get; set; }
public IPercentileRanksAggregation PercentileRanks { get; set; }
public IPercentilesAggregation Percentiles { get; set; }
public IPercentilesBucketAggregation PercentilesBucket { get; set; }
public IRangeAggregation Range { get; set; }
public IRareTermsAggregation RareTerms { get; set; }
public IReverseNestedAggregation ReverseNested { get; set; }
public ISamplerAggregation Sampler { get; set; }
public IScriptedMetricAggregation ScriptedMetric { get; set; }
public ISerialDifferencingAggregation SerialDifferencing { get; set; }
public ISignificantTermsAggregation SignificantTerms { get; set; }
public ISignificantTextAggregation SignificantText { get; set; }
public IStatsAggregation Stats { get; set; }
public IStatsBucketAggregation StatsBucket { get; set; }
public ISumAggregation Sum { get; set; }
public ISumBucketAggregation SumBucket { get; set; }
public ITermsAggregation Terms { get; set; }
public ITopHitsAggregation TopHits { get; set; }
public IValueCountAggregation ValueCount { get; set; }
public IWeightedAverageAggregation WeightedAverage { get; set; }
public IMedianAbsoluteDeviationAggregation MedianAbsoluteDeviation { get; set; }
public IMultiTermsAggregation MultiTerms { get; set; }
public IVariableWidthHistogramAggregation VariableWidthHistogram { get; set; }
public void Accept(IAggregationVisitor visitor)
{
if (visitor.Scope == AggregationVisitorScope.Unknown) visitor.Scope = AggregationVisitorScope.Aggregation;
new AggregationWalker().Walk(this, visitor);
}
public static implicit operator AggregationContainer(AggregationBase aggregator)
{
if (aggregator == null) return null;
var container = new AggregationContainer();
aggregator.WrapInContainer(container);
var bucket = aggregator as BucketAggregationBase;
container.Aggregations = bucket?.Aggregations;
var combinator = aggregator as AggregationCombinator;
if (combinator?.Aggregations != null)
{
var dict = new AggregationDictionary();
foreach (var agg in combinator.Aggregations)
dict.Add(((IAggregation)agg).Name, agg);
container.Aggregations = dict;
}
container.Meta = aggregator.Meta;
return container;
}
}
public class AggregationContainerDescriptor : DescriptorBase, IAggregationContainer>, IAggregationContainer
where T : class
{
IAdjacencyMatrixAggregation IAggregationContainer.AdjacencyMatrix { get; set; }
AggregationDictionary IAggregationContainer.Aggregations { get; set; }
IAverageAggregation IAggregationContainer.Average { get; set; }
IAverageBucketAggregation IAggregationContainer.AverageBucket { get; set; }
IBucketScriptAggregation IAggregationContainer.BucketScript { get; set; }
IBucketSelectorAggregation IAggregationContainer.BucketSelector { get; set; }
IBucketSortAggregation IAggregationContainer.BucketSort { get; set; }
ICardinalityAggregation IAggregationContainer.Cardinality { get; set; }
IChildrenAggregation IAggregationContainer.Children { get; set; }
ICompositeAggregation IAggregationContainer.Composite { get; set; }
ICumulativeSumAggregation IAggregationContainer.CumulativeSum { get; set; }
IDateHistogramAggregation IAggregationContainer.DateHistogram { get; set; }
IAutoDateHistogramAggregation IAggregationContainer.AutoDateHistogram { get; set; }
IDateRangeAggregation IAggregationContainer.DateRange { get; set; }
IDerivativeAggregation IAggregationContainer.Derivative { get; set; }
IDiversifiedSamplerAggregation IAggregationContainer.DiversifiedSampler { get; set; }
IExtendedStatsAggregation IAggregationContainer.ExtendedStats { get; set; }
IExtendedStatsBucketAggregation IAggregationContainer.ExtendedStatsBucket { get; set; }
IFilterAggregation IAggregationContainer.Filter { get; set; }
IFiltersAggregation IAggregationContainer.Filters { get; set; }
IGeoBoundsAggregation IAggregationContainer.GeoBounds { get; set; }
IGeoCentroidAggregation IAggregationContainer.GeoCentroid { get; set; }
IGeoDistanceAggregation IAggregationContainer.GeoDistance { get; set; }
IGeoHashGridAggregation IAggregationContainer.GeoHash { get; set; }
IGeoLineAggregation IAggregationContainer.GeoLine { get; set; }
IGeoTileGridAggregation IAggregationContainer.GeoTile { get; set; }
IGlobalAggregation IAggregationContainer.Global { get; set; }
IHistogramAggregation IAggregationContainer.Histogram { get; set; }
IIpRangeAggregation IAggregationContainer.IpRange { get; set; }
IMatrixStatsAggregation IAggregationContainer.MatrixStats { get; set; }
IMaxAggregation IAggregationContainer.Max { get; set; }
IMaxBucketAggregation IAggregationContainer.MaxBucket { get; set; }
IDictionary IAggregationContainer.Meta { get; set; }
IMinAggregation IAggregationContainer.Min { get; set; }
IMinBucketAggregation IAggregationContainer.MinBucket { get; set; }
IMissingAggregation IAggregationContainer.Missing { get; set; }
IMovingAverageAggregation IAggregationContainer.MovingAverage { get; set; }
IMovingFunctionAggregation IAggregationContainer.MovingFunction { get; set; }
IMultiTermsAggregation IAggregationContainer.MultiTerms { get; set; }
INestedAggregation IAggregationContainer.Nested { get; set; }
IParentAggregation IAggregationContainer.Parent { get; set; }
IPercentileRanksAggregation IAggregationContainer.PercentileRanks { get; set; }
IPercentilesAggregation IAggregationContainer.Percentiles { get; set; }
IPercentilesBucketAggregation IAggregationContainer.PercentilesBucket { get; set; }
IRangeAggregation IAggregationContainer.Range { get; set; }
IRareTermsAggregation IAggregationContainer.RareTerms { get; set; }
IReverseNestedAggregation IAggregationContainer.ReverseNested { get; set; }
ISamplerAggregation IAggregationContainer.Sampler { get; set; }
IScriptedMetricAggregation IAggregationContainer.ScriptedMetric { get; set; }
ISerialDifferencingAggregation IAggregationContainer.SerialDifferencing { get; set; }
ISignificantTermsAggregation IAggregationContainer.SignificantTerms { get; set; }
ISignificantTextAggregation IAggregationContainer.SignificantText { get; set; }
IStatsAggregation IAggregationContainer.Stats { get; set; }
IStatsBucketAggregation IAggregationContainer.StatsBucket { get; set; }
ISumAggregation IAggregationContainer.Sum { get; set; }
ISumBucketAggregation IAggregationContainer.SumBucket { get; set; }
ITermsAggregation IAggregationContainer.Terms { get; set; }
ITopHitsAggregation IAggregationContainer.TopHits { get; set; }
IValueCountAggregation IAggregationContainer.ValueCount { get; set; }
IWeightedAverageAggregation IAggregationContainer.WeightedAverage { get; set; }
IMedianAbsoluteDeviationAggregation IAggregationContainer.MedianAbsoluteDeviation { get; set; }
IVariableWidthHistogramAggregation IAggregationContainer.VariableWidthHistogram { get; set; }
public void Accept(IAggregationVisitor visitor)
{
if (visitor.Scope == AggregationVisitorScope.Unknown) visitor.Scope = AggregationVisitorScope.Aggregation;
new AggregationWalker().Walk(this, visitor);
}
public AggregationContainerDescriptor Average(string name,
Func, IAverageAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.Average = d);
public AggregationContainerDescriptor DateHistogram(string name,
Func, IDateHistogramAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.DateHistogram = d);
public AggregationContainerDescriptor AutoDateHistogram(string name,
Func, IAutoDateHistogramAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.AutoDateHistogram = d);
public AggregationContainerDescriptor Percentiles(string name,
Func, IPercentilesAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.Percentiles = d);
public AggregationContainerDescriptor PercentileRanks(string name,
Func, IPercentileRanksAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.PercentileRanks = d);
public AggregationContainerDescriptor DateRange(string name,
Func, IDateRangeAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.DateRange = d);
public AggregationContainerDescriptor ExtendedStats(string name,
Func, IExtendedStatsAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.ExtendedStats = d);
public AggregationContainerDescriptor Filter(string name,
Func, IFilterAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.Filter = d);
public AggregationContainerDescriptor Filters(string name,
Func, IFiltersAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.Filters = d);
public AggregationContainerDescriptor GeoDistance(string name,
Func, IGeoDistanceAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.GeoDistance = d);
public AggregationContainerDescriptor GeoHash(string name,
Func, IGeoHashGridAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.GeoHash = d);
public AggregationContainerDescriptor GeoLine(string name,
Func, IGeoLineAggregation> selector) =>
_SetInnerAggregation(name, selector, (a, d) => a.GeoLine = d);
public AggregationContainerDescriptor GeoTile(string name,
Func, IGeoTileGridAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.GeoTile = d);
public AggregationContainerDescriptor GeoBounds(string name,
Func, IGeoBoundsAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.GeoBounds = d);
public AggregationContainerDescriptor Histogram(string name,
Func, IHistogramAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.Histogram = d);
public AggregationContainerDescriptor Global(string name,
Func, IGlobalAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.Global = d);
public AggregationContainerDescriptor IpRange(string name,
Func, IIpRangeAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.IpRange = d);
public AggregationContainerDescriptor Max(string name,
Func, IMaxAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.Max = d);
public AggregationContainerDescriptor Min(string name,
Func, IMinAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.Min = d);
public AggregationContainerDescriptor Cardinality(string name,
Func, ICardinalityAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.Cardinality = d);
public AggregationContainerDescriptor Missing(string name,
Func, IMissingAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.Missing = d);
public AggregationContainerDescriptor MultiTerms(string name,
Func, IMultiTermsAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.MultiTerms = d);
public AggregationContainerDescriptor Nested(string name,
Func, INestedAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.Nested = d);
///
public AggregationContainerDescriptor Parent(string name,
Func, IParentAggregation> selector
) where TParent : class =>
_SetInnerAggregation(name, selector, (a, d) => a.Parent = d);
public AggregationContainerDescriptor ReverseNested(string name,
Func, IReverseNestedAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.ReverseNested = d);
public AggregationContainerDescriptor Range(string name,
Func, IRangeAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.Range = d);
public AggregationContainerDescriptor RareTerms(string name,
Func, IRareTermsAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.RareTerms = d);
public AggregationContainerDescriptor Stats(string name,
Func, IStatsAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.Stats = d);
public AggregationContainerDescriptor Sum(string name,
Func, ISumAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.Sum = d);
public AggregationContainerDescriptor Terms(string name,
Func, ITermsAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.Terms = d);
public AggregationContainerDescriptor SignificantTerms(string name,
Func, ISignificantTermsAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.SignificantTerms = d);
public AggregationContainerDescriptor SignificantText(string name,
Func, ISignificantTextAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.SignificantText = d);
public AggregationContainerDescriptor ValueCount(string name,
Func, IValueCountAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.ValueCount = d);
public AggregationContainerDescriptor TopHits(string name,
Func, ITopHitsAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.TopHits = d);
public AggregationContainerDescriptor Children(string name,
Func, IChildrenAggregation> selector
) where TChild : class =>
_SetInnerAggregation(name, selector, (a, d) => a.Children = d);
public AggregationContainerDescriptor ScriptedMetric(string name,
Func, IScriptedMetricAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.ScriptedMetric = d);
public AggregationContainerDescriptor AverageBucket(string name,
Func selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.AverageBucket = d);
public AggregationContainerDescriptor Derivative(string name,
Func selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.Derivative = d);
public AggregationContainerDescriptor MaxBucket(string name,
Func selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.MaxBucket = d);
public AggregationContainerDescriptor MinBucket(string name,
Func selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.MinBucket = d);
public AggregationContainerDescriptor SumBucket(string name,
Func selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.SumBucket = d);
public AggregationContainerDescriptor StatsBucket(string name,
Func selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.StatsBucket = d);
public AggregationContainerDescriptor ExtendedStatsBucket(string name,
Func selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.ExtendedStatsBucket = d);
public AggregationContainerDescriptor PercentilesBucket(string name,
Func selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.PercentilesBucket = d);
public AggregationContainerDescriptor MovingAverage(string name,
Func selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.MovingAverage = d);
public AggregationContainerDescriptor MovingFunction(string name,
Func selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.MovingFunction = d);
public AggregationContainerDescriptor CumulativeSum(string name,
Func selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.CumulativeSum = d);
public AggregationContainerDescriptor SerialDifferencing(string name,
Func selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.SerialDifferencing = d);
public AggregationContainerDescriptor BucketScript(string name,
Func selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.BucketScript = d);
public AggregationContainerDescriptor BucketSelector(string name,
Func selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.BucketSelector = d);
public AggregationContainerDescriptor BucketSort(string name,
Func, IBucketSortAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.BucketSort = d);
public AggregationContainerDescriptor Sampler(string name,
Func, ISamplerAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.Sampler = d);
public AggregationContainerDescriptor DiversifiedSampler(string name,
Func, IDiversifiedSamplerAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.DiversifiedSampler = d);
public AggregationContainerDescriptor GeoCentroid(string name,
Func, IGeoCentroidAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.GeoCentroid = d);
public AggregationContainerDescriptor MatrixStats(string name,
Func, IMatrixStatsAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.MatrixStats = d);
public AggregationContainerDescriptor AdjacencyMatrix(string name,
Func, IAdjacencyMatrixAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.AdjacencyMatrix = d);
public AggregationContainerDescriptor Composite(string name,
Func, ICompositeAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.Composite = d);
public AggregationContainerDescriptor WeightedAverage(string name,
Func, IWeightedAverageAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.WeightedAverage = d);
public AggregationContainerDescriptor MedianAbsoluteDeviation(string name,
Func, IMedianAbsoluteDeviationAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.MedianAbsoluteDeviation = d);
public AggregationContainerDescriptor VariableWidthHistogram(string name,
Func, IVariableWidthHistogramAggregation> selector
) =>
_SetInnerAggregation(name, selector, (a, d) => a.VariableWidthHistogram = d);
///
/// Fluent methods do not assign to properties on `this` directly but on IAggregationContainers inside
/// `this.Aggregations[string, IContainer]
///
private AggregationContainerDescriptor _SetInnerAggregation(
string key,
Func selector
, Action assignToProperty
)
where TAggregator : IAggregation, TAggregatorInterface, new()
where TAggregatorInterface : IAggregation
{
var aggregator = selector(new TAggregator());
//create new isolated container for new aggregator and assign to the right property
var container = new AggregationContainer { Meta = aggregator.Meta };
assignToProperty(container, aggregator);
//create aggregations dictionary on `this` if it does not exist already
IAggregationContainer self = this;
if (self.Aggregations == null) self.Aggregations = new Dictionary();
//if the aggregator is a bucket aggregator (meaning it contains nested aggregations);
if (aggregator is IBucketAggregation bucket && bucket.Aggregations.HasAny())
{
//make sure we copy those aggregations to the isolated container's
//own .Aggregations container (the one that gets serialized to "aggs")
IAggregationContainer d = container;
d.Aggregations = bucket.Aggregations;
}
//assign the aggregations container under Aggregations ("aggs" in the json)
self.Aggregations[key] = container;
return this;
}
//always evaluate to false so that each side of && equation is evaluated
public static bool operator false(AggregationContainerDescriptor a) => false;
//always evaluate to false so that each side of && equation is evaluated
public static bool operator true(AggregationContainerDescriptor a) => false;
public static AggregationContainerDescriptor operator &(AggregationContainerDescriptor left, AggregationContainerDescriptor right)
{
if (right == null) return left;
if (left == null) return right;
if (Equals(left, right)) return left;
var d = new AggregationContainerDescriptor();
var leftAggs = (IDictionary)((IAggregationContainer)left).Aggregations;
var rightAggs = (IDictionary)((IAggregationContainer)right).Aggregations;
foreach (var kv in rightAggs)
{
if (leftAggs.ContainsKey(kv.Key))
{
var message = $"Can not merge two {nameof(AggregationContainerDescriptor)}'s";
message += $" {kv.Key} is defined in both";
throw new Exception(message);
}
leftAggs.Add(kv.Key, kv.Value);
}
((IAggregationContainer)d).Aggregations = ((IAggregationContainer)left).Aggregations;
return d;
}
}
}