如何使用Elasticsearch进行年度聚合?

时间:2014-09-18 23:25:24

标签: elasticsearch

假设我在文档上有一个日期字段,我知道使用date_histogram聚合我可以按日,月,年等方式获得文档计数。

我想要做的是在几年内得到1月,2月,3月等的平均文件数。在几个星期内,周一,周二,周三等也是如此。是否有一种方法可以使用相同的日期字段或使用Elasticsearch实现此目的的最佳方法是什么?


示例

假设我们在三年内有一堆订单:

  • 2012年 - 1月(10个订单),2月(5个订单),3月(7个订单),4月(11个订单)等
  • 2013年 - 1月(13个订单),2月(7个订单),3月(12个订单),4月(15个订单)等
  • 2014年 - 1月(10个订单),2月(7个订单),3月(6个订单),4月(13个订单)等

我想要的是在给定年份内每个月的平均值,因此输出将是:

1月(10 + 13 + 10/3 = 11个订单),2月(6.33个订单),3月(8.33个订单),4月(13个订单)等

如果可以推广N年(或N Januaries等),那么我们最好搜索任何日期范围。

2 个答案:

答案 0 :(得分:2)

您可以像这样使用'monthOfYear':

"aggregations": {
    "timeslice": {
        "histogram": {
            "script": "doc['timestamp'].date.getMonthOfYear()",
            "interval": 1,
            "min_doc_count": 0,
            "extended_bounds": {
                "min": 1,
                "max": 12
            },
            "order": {
                "_key": "desc"
            }
        }
    }

扩展边界将确保您获得每月的值(即使它为零)。

如果您想要月份名称,您可以在自己的代码中执行此操作,或者执行此操作(结果是您将无法获得没有数据的月份的值):

"aggregations": {
    "monthOfYear": {
        "terms": {
            "script": "doc['timestamp'].date.monthOfYear().getAsText()",
            "order": {
                "_term": "asc"
            }
        }
    }

一旦你有了这个,你可以将你的统计数据聚合嵌套在这个中:

"aggregations: {
    "monthOfYear": {
        "terms": {
            ...
        },
        "aggregations": {
            "stats": ...
        }
    }
 }

这个问题现在已经很老了,但是,希望这有助于某人。

答案 1 :(得分:0)

我对你想要的理解是:

您希望看到每年每月的平均文件数量

是正确的吗?

如果是这样,你可以计算一年中的文件数量(即年度桶),然后用脚本除以12。

E.g。显示每周桶中的每日平均文件数(假设每月30天):

curl -XGET 'http://localhost:9200/index/type/_search?pretty' -d '{
  "aggs" : {
    "monthly_bucket": {
         "date_histogram": {"field": "datefield","interval": "week"},
              "aggs" : {
                    "weekly_average": {"sum" : {"script" : " doc[\"datefield\"].value>0 ? 1/30 : 0"} }}
         }
     }
}'