5

I have the following query in NEST (ElasticSearch C# client), note the nested aggregation:

            var query = _elasticClient.Search<Auth5209>(s => s
                .Size(0)
                .Aggregations(a=> a
                    .Terms("incidentID", t=> t
                        .Field(f=>f.IncidentID)
                        .Size(5)
                        .Aggregations(a2 => a2
                            .Stats("authDateStats", s1=>s1.Field(f=>f.AuthEventDate))
                        )
                    )                        
                )
                );

This correctly generates the following query:

{
  "size": 0,
  "aggs": {
    "incidentID": {
      "terms": {
        "field": "incidentID",
        "size": 5
      },
      "aggs": {
        "authDateStats": {
          "stats": {
            "field": "authEventDate"
          }
        }
      }
    }
  }
}

Which gives me the following results:

"aggregations" : {
    "incidentID" : {
        "buckets" : [{
                "key" : "0A631EB1-01EF-DC28-9503-FC28FE695C6D",
                "doc_count" : 233,
                "authDateStats" : {
                    "count" : 233,
                    "min" : 1401167036075,
                    "max" : 1401168969907,
                    "avg" : 1401167885682.6782,
                    "sum" : 326472117364064
                }
            }
        ]
    }
}

What I can't figure out is how I access the "authDateStats" section. When I debug I don't see any way to access the data.

enter image description here

1

3 Answers 3

6

Neither the official documentation nor the answers here fully work for nest 2.0+. Although the answer from jhilden did get started me down the right path.

Here is a working example of a similar query which can be used with nest 2.0+:

        const string termsAggregation = "device_number";
        const string topHitsAggregation = "top_hits";

        var response = await _elasticsearchClient.Client.SearchAsync<CustomerDeviceModel>(s => s
            .Aggregations(a => a
                .Terms(termsAggregation, ta => ta
                    .Field(o => o.DeviceNumber)
                    .Size(int.MaxValue)
                    .Aggregations(sa => sa
                        .TopHits(topHitsAggregation, th => th
                            .Size(1)
                            .Sort(x => x.Field(f => f.Modified).Descending())
                        )
                    )
                )
            )
        );

        if (!response.IsValid)
        {
            throw new ElasticsearchException(response.DebugInformation);
        }

        var results = new List<CustomerDeviceModel>();
        var terms = response.Aggs.Terms(termsAggregation);

        foreach (var bucket in terms.Buckets)
        {
            var hit = bucket.TopHits(topHitsAggregation);
            var device = hit.Documents<CustomerDeviceModel>().First();
            results.Add(device);
        }
Sign up to request clarification or add additional context in comments.

Comments

3

I'm guessing you already figured this out but you can access the nested aggregations, it's just in a base class, you can see it in Nest.KeyItem.base.base.Aggregations in the debugger.

Comments

1

Here is a full working sample of accessing an inner aggregation:

        const string aggName = "LocationIDAgg";
        const string aggNameTopHits = "LatestForLoc";
        var response = await ElasticClient.SearchAsync<PlacementVerificationES>(s => s
            .Query(BuildQuery(filter, null))                
            .Size(int.MaxValue)
            .Aggregations(a=> a
                .Terms(aggName, t=> t
                    .Field(f=>f.LocationID)
                    .Size(100)
                    .Aggregations(innerAgg => innerAgg
                        .TopHits(aggNameTopHits, th=> th
                            .Size(1)
                            .Sort(x=>x.OnField(f=> f.Date).Descending())
                        )
                    )
                )
            )
        ).VerifySuccessfulResponse();

        //var debug = response.GetRequestString();
        var agBucket = (Bucket)response.Aggregations[aggName];

        var output = new List<PlacementVerificationForReporting>();
        // ReSharper disable once LoopCanBeConvertedToQuery
        // ReSharper disable once PossibleInvalidCastExceptionInForeachLoop
        foreach (KeyItem i in agBucket.Items)
        {
            var topHits = (TopHitsMetric)i.Aggregations[aggNameTopHits];
            var top1 = topHits.Hits<PlacementVerificationES>().Single();
            var reportingObject = RepoToReporting(top1);
            output.Add(reportingObject);
        }

        return output;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.