.Net Client - Nested aggregations always returning 0

Hi all,

I am using the new .net client and I am trying to perform aggregations on some nested documents but the count is always being returned as 0.

Consider the following class structure:

public class Venue {
          public string Name {get; set;}
          public string Location {get; set;}
          public string PromotedLocations {get; set;} // Comma separated list of locations
          public List<Product> Products {get; set;} = new List<ProductData>();
    }

    public class Product {
          public int Nights {get; set;}
          public int Guests {get; set;}
          public List<PriceData> Pricing {get; set;} = new List<PriceData>();
    }

    public class PriceData {
          public double SalePrice {get; set;}
          public double WasPrice {get; set;}
          public DateTime StartDate {get; set;}
          public DateTime EndDate {get; set}
          public string Currency {get; set;}
    }

I've declared products as Nested when I define my index as follows:

await _elasticsearchClient.Indices.CreateAsync<VenueResult>(finalIndexName, c =>
                c.Mappings(m => m
                    .Properties(properties => properties
                        .Nested(n => n.Products,
                            npd => npd.Properties(
                                np => np
                                    .Keyword(k => k.Products.First().Nights)
                                    .Keyword(k => k.Products.First().Guests)
                                    .Object(o => o.Products.First().Pricing.First(), x => x.Properties(p => p.Keyword(k => k.Products.First().Pricing.First().Currency)))
                            )
                        )
                    )
                )
            );

And when I perform my search, I am doing the following to build the aggregations:

Dictionary<string, Aggregation> lowerLevelAggregations = new Dictionary<string, Aggregation>();
        lowerLevelAggregations.Add("guests", Aggregation.Terms(new TermsAggregation()
            {
                Field = "products.guests",
                Size = 500
            })
        );
        lowerLevelAggregations.Add("nights", Aggregation.Terms(new TermsAggregation()
            {
                Field = "products.nights",
                Size = 500
            })
        );
        lowerLevelAggregations.Add("price-per-person", Aggregation.Range(new RangeAggregation()
        {
            Field = "products.pricing.salePrice",
            Ranges = new List<AggregationRange>()
            {
                new AggregationRange()
                {
                    From = 50,
                    To = 299,
                    Key = "£50-£299"
                },
                new AggregationRange()
                {
                    From = 300,
                    To = 349,
                    Key = "£300-£349"
                },
                new AggregationRange()
                {
                    From = 350,
                    To = 799,
                    Key = "£350-£799"
                },
                new AggregationRange()
                {
                    From = 800,
                    To = 1149,
                    Key = "£800-£1149"
                },
                new AggregationRange()
                {
                    From = 1150,
                    To = 1699,
                    Key = "£1150-£1699"
                },
                new AggregationRange()
                {
                    From = 1700,
                    Key = "£1700+"
                }
            }
        }));

        var topLevelAggregation = Aggregation.Nested(new NestedAggregation()
        {
            Path = "products"
        }).Aggregations = lowerLevelAggregations;
        
        var searchRequest = new SearchRequest("my-index")
        {
            From = 0,
            Size = 10,
            Aggregations = topLevelAggregation
        };

When I perform my search, I get results returned but the aggregations are 0 despite there being child documents returned as part of the main documents. What am I doing wrong? The documentation for all of this is really lacking compared to NEST and I'm mostly having to go through multiple iterations of trial and error in order to try and get this working.

Hi @jespin,

the documentation for this exact use-case is available here:

Your mappings and the composition of the sub-aggregations looks good!

The only part that must change is this one:

var topLevelAggregation = Aggregation.Nested(new NestedAggregation()
{
	Path = "products"
});

topLevelAggregation.Aggregations = lowerLevelAggregations;

var searchRequest = new SearchRequest("my-index")
{
	From = 0,
	Size = 10,
	Aggregations = new Dictionary<string, Aggregation>
	{
		{ "top-level", topLevelAggregation }
	}
};

Your previous statement:

var topLevelAggregation = Aggregation.Nested(new NestedAggregation()
{
    Path = "products"
}).Aggregations = lowerLevelAggregations;

used a C# syntax that's not very common:

var x = a = b = 1;

assigns 1 to x, a and b at the same time. This is what happened in your case, causing topLevelAggregation to actually point to the sub-aggregations of the top-level "Nested" aggregation.

I did stumble across that document page but it wasn't really helpful as it didn't seem to mention anything about nested documents. I made the amendments you suggested and can now see the nested aggregates coming back. Is there a special syntax required for then passing in those aggregations as filters? Ideally I want to return the parent document based on whether or not the child documents contain certain props returned in the aggregation. Sorry, its just the Nest documentation was a lot clearer.