有没有好的"从ES嵌套聚合中获取规范化数据行的方法?

时间:2017-03-20 08:54:54

标签: javascript node.js elasticsearch elasticsearch-aggregation

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
}]

从上述嵌套结构中获取此结果的最佳方法是什么,或者如果可能的话,从弹性搜索本身获得更好的结果。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

在简单的Javascript中,您可以使用迭代和递归方法 - 但我建议使用ES的某些功能来获得想要的结果。



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));