【问题标题】:Elasticsearch how sum values after aggregation resultElasticsearch如何汇总结果后的值
【发布时间】:2016-11-22 02:58:05
【问题描述】:

我在 Elasticsearch 索引下有很多文档如下:

{
        "_index": "f2016-07-17",
        "_type": "trkvjadsreqpxl.gif",
        "_id": "AVX2N3dl5siG6SyfyIjb",
        "_score": 1,
        "_source": {
          "time": "1468714676424",
          "meta": {
            "cb_id": 25681,
            "mt_id": 649,
            "c_id": 1592,
            "revenue": 2.5,
            "mt_name": "GMS-INAPP-EN-2.5",
            "c_description": "COULL-INAPP-EN-2.5",
            "domain": "wv.inner-active.mobi",
            "master_domain": "649###wv.inner-active.mobi",
            "child_domain": "1592###wv.inner-active.mobi",
            "combo_domain": "25681###wv.inner-active.mobi",
            "ip": "52.42.87.73"
          }
        }
      }

我想在多个字段上进行日期直方图/范围聚合并将结果存储在其他集合/索引中。 所以我可以使用小时范围之间的查询/聚合来计算 doc_count 总和。

聚合是:

{
  "aggs": {
    "hour":{
      "date_histogram": {
        "field": "time",
        "interval": "hour"
      },
      "aggs":{
            "hourly_M_TAG":{
               "terms":{
                  "field":"meta.mt_id"
               }
            }
         }....
    }
  }
} 

结果如预期:

"aggregations": {
    "hour": {
      "buckets": [
        {
          "key_as_string": "2016-07-17T00:00:00.000Z",
          "key": 1468713600000,
          "doc_count": 94411750,
          "hourly_M_TAG": {
            "doc_count_error_upper_bound": 1485,
            "sum_other_doc_count": 30731646,
            "buckets": [
              {
                "key": 10,
                "doc_count": 10175501
              },
              {
                "key": 649,
                "doc_count": 200000
              }....
            ]
          }
        },
        {
          "key_as_string": "2016-07-17T01:00:00.000Z",
          "key": 1468717200000,
          "doc_count": 68738743,
          "hourly_M_TAG": {
            "doc_count_error_upper_bound": 2115,
            "sum_other_doc_count": 22478590,
            "buckets": [
              {
                "key": 559,
                "doc_count": 8307018
              },
              {
                "key": 649,
                "doc_count" :100000
              }...

假设我解析响应并尝试将结果存储在其他索引/集合中。

我的问题

存储聚合结果的最佳方式是什么, 所以我可以进行其他查询/聚合来汇总不同小时范围之间的“doc_count”?

例如:在“2016-07-17T00:00:00.000Z”-“2016-07-17T01:00:00.000Z”之间想要查看每个键的总 doc_count

预期结果:

{
          "range_sum": {
            "buckets": [
              {
                "key": 649,
                "doc_count": 300000 // (200000+100000)
              },
              {
                "key": 588,
                "doc_count": 2928548 // ... + ...
              }....
            ]
          }
        }

谢谢!

【问题讨论】:

    标签: java elasticsearch lucene aggregate aggregation


    【解决方案1】:

    我可能把你的最终目标弄错了,但在我看来你想要的 在可配置的时间范围内,meta.mt_id 的每个值的总 doc_count

    如果是这种情况,我认为您不需要存储第一次聚合的结果,您真的只需要更改间隔值以反映您想要的存储桶大小。如果您想要 meta.mt_id 的每个值的总计,则翻转聚合可能会有所帮助,以便您首先按术语聚合,然后按日期聚合:

    {
        "size": 0,
        "aggs": {
        "hourly_M_TAG": {
          "terms": {
            "field": "meta.mt_id"
          },
          "aggs": {
          "hour": {
            "date_histogram": {
              "field": "time",
              "interval": "2h"
            }
          }
        }
      }
    }
    

    这将为您提供每个 meta.mt_id 的结果,如果您希望在特定时间范围内添加总计,只需更改间隔以反映这一点。

    编辑:

    可能有一些智能的弹性搜索方式可以做到这一点,但我想我会这样做:

    做你原来的聚合

    foreach bucket in buckets:
        index:
            {
                "id" : {meta.id},
                "timestamp" : {key_as_string}
                "count" : {doc_count}
            }
    

    然后,您应该拥有所有meta.id 文档及其doc_count 在不同时间戳的索引,间隔的粒度取决于您的需要。

    然后,您可以对日期使用范围过滤器(假设使用 elasticsearch 2.x)对新索引进行 term->sum 聚合:

    {
      "size": 0,
      "filter": {
        "range": {
          "timestamp": {
            "gte": "now-1h",
            "lte": "now"
          }
        }
      },
      "aggs": {
        "termName": {
          "terms": {
            "field": "id"
          },
          "aggs": {
            "sumCounts": {
              "sum": {
                "field": "count"
              }
            }
          }
        }
      }
    }
    

    很抱歉,如果这仍然不是您想要的,我认为有很多不同的方法可以做到这一点。

    【讨论】:

    • Mic987:我已经清楚地添加了预期的结果。我需要存储结果,因为用户的请求可以从任何时间到任何时间,另一个问题是我没有剩余存储空间,所以我每天汇总数据,1天后没有这种汇总,就会出现存储空间问题.
    • 我已经更新了我的答案,希望它有一些用处,我认为有很多不同的方法可以实现你想要的。
    猜你喜欢
    • 2016-02-06
    • 1970-01-01
    • 2021-12-08
    • 2015-06-27
    • 2011-09-30
    • 1970-01-01
    • 2020-01-27
    • 1970-01-01
    • 2015-03-25
    相关资源
    最近更新 更多