Elasticsearch如何汇总结果后的值

Posted

技术标签:

【中文标题】Elasticsearch如何汇总结果后的值【英文标题】:Elasticsearch how sum values after aggregation result 【发布时间】: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 // ... + ...
              ....
            ]
          
        

谢谢!

【问题讨论】:

【参考方案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天后没有这种汇总,就会出现存储空间问题. 我已经更新了我的答案,希望它有一些用处,我认为有很多不同的方法可以实现你想要的。

以上是关于Elasticsearch如何汇总结果后的值的主要内容,如果未能解决你的问题,请参考以下文章

Elasticsearch:运用 Python 来实现对搜索结果的分页

如何使弹性搜索多匹配模糊搜索始终返回最小数量的结果

Elasticsearch常见问题汇总——持续更新

Elasticsearch常见问题汇总——持续更新

ES(ElasticSearch) 索引创建

Elasticsearch如何在Elasticsearch中查找相似的术语