我在Elasticsearch中处理的文档的持续时间概念表示为开始和结束时间,例如
{
issueId: 1,
issuePriority: 3,
timeWindow: {
start: "2015-10-14T17:00:00-07:00",
end: "2015-10-14T18:00:00-07:00"
}
},
{
issueId: 2,
issuePriority: 1,
timeWindow: {
start: "2015-10-14T16:50:00-07:00",
end: "2015-10-14T17:50:00-07:00"
}
}
我的目标是生成一个直方图,其中问题的数量及其最大优先级被汇总到15分钟的桶中。因此,对于上面的示例,issue #1
将被17:00
,17:15
,17:30
和17:45
存储桶中的文字化,不多也不少。
我尝试使用date_histogram
聚合,例如:
aggs: {
max_priority_over_time: {
date_histogram: {
field: "timeWindow.start",
interval: "15minute",
},
aggs: {
max_priority: ${top_hits_aggregation}
}
}
}
但显然它只是issue #1
桶中的17:00
。即使我考虑timeWindow.end
,它也只会被添加到18:00
桶中。有谁知道如何使用date_histogram
或其他Elasticsearch聚合来实现这一目标?潜在地生成从timeWindow.start
到timeWindow.end
之间15分钟的时间戳范围,以便它们可以正确地进行bucketized。感谢。
答案 0 :(得分:1)
根据定义,bucketing操作会将查询返回的每个对象放入一个存储桶中,只有一个存储桶,即,您不能让它在一个查询中同时将同一个对象放在多个存储桶中。
如果我正确理解您的问题,那么您需要执行一系列查询,应用range filter来获取每15分钟间隔内的问题数。因此,对于您定义的每个区间,您将获得在该区间内打开的问题:
{
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
"range": {
"timeWindow.start" : {
"lte" : "2015-10-14T17:00:00-07:00"
}
},
"range": {
"timeWindow.end" : {
"gte" : "2015-10-14T17:15:00-07:00"
}
},
]
}
}
}
}
}
(您需要将max_priority
聚合添加到查询中。)
范围查询将由elasticsearch缓存,因此这应该相当有效。假设您的历史数据没有改变,您也可以在应用程序中缓存历史间隔的结果。
答案 1 :(得分:1)
您需要使用脚本。创建一个发出日期数组的脚本。这些日期应从开始日期开始,每个日期应增加15分钟(假设15分钟为间隔)。现在将此脚本放在date_histogram的脚本选项中。 所以基本上脚本应该执行以下操作 -
start=2015-10-14T17:00:00-07:00
end=2015-10-14T18:00:00-07:00"
Output of script = [ "2015-10-14T17:00:00-07:00" , "2015-10-14T17:15:00-07:00" , "2015-10-14T17:30:00-07:00" , "2015-10-14T17:45:00-07:00" , "2015-10-14T18:00:00-07:00" ]
要更多地依靠脚本编写,您可以浏览此Elasticsearch documentations。这些博客可能也很有用 - This,this和this。
答案 2 :(得分:1)
好的,由于我的数据的时间戳总是被截断到最接近的10分钟,我想我可以使用nested terms aggregation
代替:
aggs: {
per_start_time: {
terms: {
field: "timeWindow.start"
},
aggs: {
per_end_time: {
terms: {
field: "timeWindow.end"
},
aggs: {
max_priority: ${top_hits_aggregation}
}
}
}
}
}
这为每个end_time的start_time提供了一个嵌套存储桶,例如:
{
"key": 1444867800000,
"key_as_string": "2015-10-15T00:10:00.000Z",
"doc_count": 11,
"per_end_time": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 1444871400000,
"key_as_string": "2015-10-15T01:10:00.000Z",
"doc_count": 11,
"max_priority": {
"hits": {
"total": 11,
"max_score": 4,
}
}
}
]
}
}
通过修剪我们后端的桶(ruby on rails),我可以得到以下结果:
[
{
"start_time": "2015-10-14 14:40:00 -0700",
"end_time": "2015-10-14 15:40:00 -0700",
"max_priority": 4,
"count": 12
}
],
[
{
"start_time": "2015-10-14 14:50:00 -0700",
"end_time": "2015-10-14 15:50:00 -0700",
"max_priority": 4,
"count": 12
}
],
...
当然可以在弹性搜索之外进一步映射/缩减为具有任意时间桶的日期直方图。如果timeWindow.start
,timeWindow.end
和窗口持续时间在时间上完全是任意的,我想它相当于只需获取所有内容并在后端进行计数(因为它几乎生成了一个嵌套的时间桶每个文件),幸运的是,我处理的时间戳有些可预测,所以我可以采取这种混合方法。