是否有一个“好”的方法来从ES嵌套聚合获得规范化的数据行?

Elasticsearch嵌套聚合允许您有效地按多个字段进行分组。 但它返回的是为每个分组嵌套的桶。

我需要的是每个组合的对象数组。

我的查询:

{ index : 'stats', type : 'click', size : 0, body : { aggs : { publisher : { terms : { field : 'publisherData.id' }, aggs : { advertiser : { terms : { field : 'advertiserData.id' }, aggs : { country : { terms : { field : 'request.location.country.iso_code' }, aggs : { revenue : { sum : { field : 'revenueData.data.USD' } }, cost : { sum : { field : 'costData.data.USD' } } } } } } } } } } } 

结果,每个字段限制为一个条目。 通常情况下,会有更多的嵌套字段的所有组合将被映射到一个数组,以便在表中显示。

 { "took": 562, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 4812178, "max_score": 0, "hits": [] }, "aggregations": { "publisher": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 3114671, "buckets": [ { "key": 4, "doc_count": 1697507, "advertiser": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 555390, "buckets": [ { "key": 5, "doc_count": 1142117, "country": { "doc_count_error_upper_bound": 13807, "sum_other_doc_count": 544585, "buckets": [ { "key": "us", "doc_count": 424137, "revenue": { "value": 772282 }, "cost": { "value": 53698.84903321415 } } ] } } ] } } ] } } } 

我需要什么(通常这里会有多个对象,每个嵌套字段组合一个):

 [{ publisher:4, advertiser:5, country:'us', cost:53698.84903321415, revenue:772282 }] 

从上面的嵌套结构得到这个结果的最好方法是什么,或者如果可能的话,从elasticsearch本身得到更好的结果。

任何帮助不胜感激。

在简单的Javascript中,您可以使用迭代和recursion的方法 – 但我build议使用ES的某些function来获得所需的结果。

 function getValues(object) { function iter(o, p) { var add = false; Object.keys(o).forEach(function (k) { if (['key', 'doc_count'].indexOf(k) !== -1) { return; } if (Array.isArray(o[k].buckets)) { o[k].buckets.forEach(function (a) { iter(a, p.concat([[k, a.key]])); }); return; } add = true; p.push([k, o[k].value]); }); add && result.push(Object.assign({}, ...p.map(a => ({[a[0]]: a[1]})))); } var result = []; iter(object.aggregations, []); return result; } var data = { took: 562, timed_out: false, _shards: { total: 5, successful: 5, failed: 0 }, hits: { total: 4812178, max_score: 0, hits: [] }, aggregations: { publisher: { doc_count_error_upper_bound: 0, sum_other_doc_count: 3114671, buckets: [{ key: 4, doc_count: 1697507, advertiser: { doc_count_error_upper_bound: 0, sum_other_doc_count: 555390, buckets: [{ key: 5, doc_count: 1142117, country: { doc_count_error_upper_bound: 13807, sum_other_doc_count: 544585, buckets: [{ key: "us", doc_count: 424137, revenue: { value: 772282 }, cost: { value: 53698.84903321415 } }] } }] } }] } } }; console.log(getValues(data));