弹性搜索NEST:读取多级深度聚合

时间:2017-01-13 17:14:17

标签: c# elasticsearch nest

我确实需要一些C#NEST的帮助我试图解决这个问题好几天了:

情况: 我有一个查询返回多种类型的文档,我已经进行了聚合以列出具有相应doc_counts的所有类型。因此,对于即时类型,Ticket在此搜索操作中有299张票。

现在我需要获取数据,根据我需要执行以下操作的文档:(https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/nested-aggregation-usage.html#_handling_responses_25

var tags = response.Aggs.Nested("tags");
var tagNames = tags.Terms("tag_names");

这将适用于一个级别的深层次的aggegrations,但我的更深层次。

这是Aggs条款:

"aggs": {
        "filtered_types": {
            "terms": {
                "field": "_type"
            }
        },
        "all_types": {
            "global": {},
            "aggs": {
                "all_result_types": {
                    "filter": {
                        "bool": {
                            "must": [
                               {
                                   "query_string": {
                                      "default_field": "_all",
                                      "query": "\"test\""
                                   }
                               }
                            ]
                        }
                    },
                    "aggs": {
                        "result_types": {
                            "terms": {
                                "field": "_type"
                            }
                        }
                    }
                } 
           }
        }
    }

我的回应将是:

"aggregations": {
      "filtered_types": {
         "doc_count_error_upper_bound": 0,
         "sum_other_doc_count": 0,
         "buckets": [
            {
               "key": "ticket",
               "doc_count": 105
            },
            {
               "key": "iteration",
               "doc_count": 10
            }
         ]
      },
      "all_types": {
         "doc_count": 2516,
         "all_result_types": {
            "doc_count": 193,
            "result_types": {
               "doc_count_error_upper_bound": 0,
               "sum_other_doc_count": 0,
               "buckets": [
                  {
                     "key": "ticket",
                     "doc_count": 105
                  },
                  {
                     "key": "comment",
                     "doc_count": 67
                  },
                  {
                     "key": "iteration",
                     "doc_count": 10
                  },
                  {
                     "key": "profile",
                     "doc_count": 6
                  },
                  {
                     "key": "project",
                     "doc_count": 3
                  },
                  {
                     "key": "company",
                     "doc_count": 1
                  },
                  {
                     "key": "sla",
                     "doc_count": 1
                  }
               ]
            }
         }
      }
   }

响应是正确的,这正是我需要的,但是对于NEST,我似乎无法进入我的数据所在的“result_types”。

我希望有人能指出我获得数据的解决方案。

1 个答案:

答案 0 :(得分:0)

"result_types"术语聚合的桶是"all_result_types"过滤器聚合的子聚合,它本身是"all_types"全局聚合的子聚合。为了获得桶,我们只需要遍历响应类型中的聚合

var searchResponse = client.Search<Document>(s => s
    .Aggregations(a => a
        .Terms("filtered_types", t => t
            .Field("_type")
        )
        .Global("all_types", g => g
            .Aggregations(aa => aa
                .Filter("all_result_types", f => f
                    .Filter(ff => ff
                        .Bool(b => b
                            .Must(q => q
                                .QueryString(qs => qs
                                    .DefaultField("_all")
                                    .Query("\"test\"")
                                )
                            )
                        )
                    )
                    .Aggregations(aaa => aaa
                        .Terms("result_types", t => t
                            .Field("_type")
                        )
                    )
                )
            )
        )
    )
);

// get the global aggregation 
var globalAggs = searchResponse.Aggs.Global("all_types");

// get the filter aggregation
var filterAggs = globalAggs.Filter("all_result_types");

// get the terms aggregation
var termsAggs = filterAggs.Terms("result_types");

// do something with the buckets
foreach (var bucket in termsAggs.Buckets)
{
    Console.WriteLine($"key: {bucket.Key}, count: {bucket.DocCount}");
}