TL; DR:我想在 elasticsearch 中使用桶做与 Haskell 的zipWith等效的操作。
我有一个带有时间和值“元组”的索引,每个条目还有一个head_id
, 指向有关一系列此类元组的元信息。这是时间序列 ID。可视化它可能看起来像这样:
head_id | timestamp | value
---------+---------------+-------
1 | 1104537600000 | 10
1 | 1104538500000 | 20
1 | 1104539400000 | 30
2 | 1104537600000 | 1000
2 | 1104538500000 | 2000
2 | 1104539400000 | 3000
为了清楚起见,让我们将每个单独的时间序列表示为这样的列表:
1: [ 10, 20, 30]
2: [1000, 2000, 3000]
我想要实现的是在弹性搜索聚合中将这些系列“压缩”在一起:假设我想要sum
它们:
result: [1010, 2020, 3030]
我目前需要获取所有数据并在应用程序代码中执行所需的操作。现在,为了节省内存和网络带宽,我想直接在elasticsearch中执行一些这样的操作。
在这种情况下,因为我想加起来的值共享相同的时间戳,所以我能够使用带有子聚合的terms
存储桶聚合来实现这一点sum
GET /timeseries/_search
{
"aggs": {
"result": {
"terms": {"field": "timestamp"},
"aggs": {
"values_sum": {
"sum": {"field": "value"}
}
}
}
}
}
返回(简化):
{
"aggregations": {
"result": {
"buckets": [
{
"key": 1104537600000,
"doc_count": 2,
"values_sum": {"value": 1010}
},
{
"key": 1104538500000,
"doc_count": 2,
"values_sum": {"value": 2020}
},
{
"key": 1104539400000,
"doc_count": 2,
"values_sum": {"value": 3030}
}
]
}
}
}
但是,在我的情况下,不能保证时间序列的时间戳会像这样对齐,这意味着我需要一种更通用的方法来聚合 2 个(或更通用的 N)时间序列,假设它们每个具有相同数量的值。
我想到的一个潜在解决方法是将每个时间序列的开头移到 0,然后使用上述技术。但是,我不知道我怎么能做到这一点。
我想到的另一个潜在解决方法是首先聚合head_id
以获取每个时间序列的存储桶,然后使用类似串行差分聚合的lag=1
东西。但是我不能使用该聚合,因为我想做除减法之外的其他操作,并且它需要通过histogram
聚合生成存储桶,而我的情况并非如此。