0
votes

I get these results in my Elastic query:

"Results" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "73c47133-8656-45e7-9499-14f52df07b70",
          "doc_count" : 1,
          "foo" : {
            "doc_count" : 40,
            "bar" : {
              "doc_count" : 1,
              "customscore" : {
                "value" : 10.496919917864476
              }
            }
          }
        }
      ]

I am trying to get a list of anonymous objects with the key field as the key and customscore field as the value.

No matter what I try, I can't seem to write code in Nest that accesses the customscore value. Apparently, I'm the very first person in the world to use nested Aggregations with the Nest library. Either that, or the documentation is very lacking. I can easily reach the Buckets:

response?.Aggregations.Terms("Results").Buckets;

But I have no idea what to do with this object. Buckets contains several objects, which I would assume I could navigate by doing this:

bucketObject["foo"]["bar"]["customscore"]

But apparently not. I have found solutions that use for loops, solutions with long Linq queries, and all of them seem to return null for me. What am I missing?

1
Hi Joe, thank you so much for all your help these last 2 weeks. I have hacked a solution together by just converting the Buckets property to a NewtonSoft JObject, and using NewtonSoft to get the data I want. This is 3 lines of code, two of which are very simple Linq Select queries. It's hacky but very short and readable. And surprisingly, shorter than any of the official Elastic examples I've seen so far. - yesman
If it works, it works :) - Joe - Elasticsearch Handbook
What's the query, and the full response? - Russ Cam

1 Answers

1
votes

Assuming the following query, which I think would match the response in the question

var client = new ElasticClient();

var response = client.Search<object>(s => s
    .Index("some_index")
    .Aggregations(a => a
        .Terms("Results", t => t
            .Field("some_field")
            .Aggregations(aa => aa  
                .Filter("foo", f => f
                    .Filter(q => q.MatchAll())
                    .Aggregations(aaa => aaa
                        .Filter("bar", ff => ff
                            .Filter(q => q.MatchAll())
                            .Aggregations(aaaa => aaaa
                                .ValueCount("customscore", vc => vc
                                    .Field("some_other_field")
                                )
                            )
                        )
                    )
                )
            )
        )
    )
);

To get a collection of anonymous types would be

var kvs = response.Aggregations.Terms("Results").Buckets
    .Select(b => new 
    { 
        key = b.Key, 
        value = b.Filter("foo").Filter("bar").ValueCount("customscore").Value 
    });

.Aggregations exposes methods that convert the IAggregate response to the expected type