Home > database >  Creating dynamic range aggregations in Nest
Creating dynamic range aggregations in Nest

Time:11-07

I have a set of POCO facets with ranges, that I have received from a client. I need to convert these ultimately into an AggregationDictionary. I cannot figure out the syntax for creating a dynamic set of aggregations (possilbly of type RangeAggregationDescriptor) and need help with this.

My POCO objects are below:

public class TypedFacets
{
    public string Name { get; set; }
    public string Field { get; set; }
    public IReadOnlyCollection<Range> RangeValues { get; set; } = new List<Range>();
    public int Size { get; set; }
}

public class Range
{
    public string Name { get; set; }
    public double? From { get; set; }
    public double? To { get; set; }
}

The Nest generation looks like below:

var facets = new List<TypedFacets>()
{
    new TypedFacets()
    {
        Name = "potatoRange",
        Field = "potatoRange",
        RangeValues = new List<Range>()
        {
            new Range()
            {
                From = 0,
                To = null,
                Name = "chips"
            },
            new Range()
            {
                From = 1,
                To = null,
                Name = "crisps"
            }
        }
    }
};

var aggregations = new AggregationContainerDescriptor<Template>();

facets.Where(f => f.RangeValues.Any()).ToList().ForEach(f =>
{
    var rad = new RangeAggregationDescriptor<Template>();

    f.RangeValues.ToList().ForEach(rangeValue =>
    {
        rad = rad.Ranges(rs => rs.From(rangeValue.From).To(rangeValue.To).Key(rangeValue.Name));
    });

    // this line doesn't work and needs to change
    aggregations.Range(f.Name, r => r
        .Field(f.Field).Ranges(rs => rad.Ranges));
});

return ((IAggregationContainer)aggregations).Aggregations;

I'm not sure how to fix the above. Any help would be appreciated.

CodePudding user response:

I eventually found the solution for this. You can create the dynamic ranges as per below

private Func<AggregationRangeDescriptor, IAggregationRange>[] CreateRangeRanges(TypedFacets rangedAgg)
{
    var rangeRanges = new List<Func<AggregationRangeDescriptor, IAggregationRange>>();

    rangedAgg.RangeValues.ToList().ForEach(rangeValue =>
    {
        rangeRanges.Add(rs => rs.From(rangeValue.From).To(rangeValue.To).Key(rangeValue.Name));
    });

    return rangeRanges.ToArray();
}

And then assing them like below

facets.Where(f => f.RangeValues.Any()).ToList().ForEach(f =>
{
    aggregations.Range(f.Name, r => r
        .Field(f.Field).Ranges(CreateRangeRanges(f)));
});
  • Related