ElasticSearch 聚合 - buckets/scripted_metric
ElasticSearch aggregation - buckets/scripted_metric
我尝试为索引中的每个文档计算速率函数 rate(val,ts)= v2-v1/t2-t1。
我的映射格式为:{ "name":keyword","value":"double","timestamp":"integer"}。
举个例子,如果我的索引中有 2 个文档:
doc1:{"name":name1,"value":5,"timestamp":2 }
doc2: {name":name1,"value":10,"timestamp":3 },
我需要得到 结果(ts=3) = (10-5)/(3-2).
在 elasticsearch 中有什么方法可以做到这一点吗?
我尝试以这种形式编写自己的指标脚本:
GET test1/_search
{
"size":15,
"aggs":{
"sum_the_hard_way": {
"scripted_metric": {
"init_script": {
"source": "state.values = []; state.timestamps = [];"
},
"map_script": {
"source": "state.values.add(doc['value'].value);state.timestamps.add(doc['timestamp'].value);"
},
"combine_script": {
"source": "def rates = []; for ( int i = 0; i <= state.values.size()-1 ; i++ ) { rate[i+1] = (state.value[i+1]- state.value[i])/(state.timestamp[i+1]- state.timestamp[i]);} return values"
},
"reduce_script": {
"source": "def vals = []; for (a in states) { vals.add(a) } return vals"
}
}
}
}
}
但是不行,我得到了
"reason" : "index_out_of_bounds_exception: Index 0 out of bounds for
length
提前致谢!
TLDR;
某些类型滑入了您的代码。
希望我已经修好了。
GET /so_agg_painless/_search
{
"size":15,
"aggs":{
"sum_the_hard_way": {
"scripted_metric": {
"init_script": {
"source": """
state.values = [];
state.timestamps = [];
"""
},
"map_script": {
"source": """
state.values.add(doc['value'].value);
state.timestamps.add(doc['timestamp'].value);
"""
},
"combine_script": {
"source": """
def rates = [];
for ( int i = 0; i <= state.values.size()-2 ; i++ ) {
def nom = (state.values[i+1]- state.values[i]);
def denom = (state.timestamps[i+1]- state.timestamps[i]);
rates.add(nom/denom);
}
return rates
"""
},
"reduce_script": {
"source": """
def vals = [];
for (a in states) {
vals.add(a)
}
return vals
"""
}
}
}
}
}
嘿伙计,你的代码中有很多拼写错误,这就是它失败的原因。
但我认为逻辑是完美的,所以对你表示敬意,所以我们非常接近。
您需要注意代码中的那些s
。
也正如您在我发布的代码中看到的那样。使用 """
。所以你可以缩进代码,这样更容易阅读和修复。
我尝试为索引中的每个文档计算速率函数 rate(val,ts)= v2-v1/t2-t1。
我的映射格式为:{ "name":keyword","value":"double","timestamp":"integer"}。
举个例子,如果我的索引中有 2 个文档:
doc1:{"name":name1,"value":5,"timestamp":2 } doc2: {name":name1,"value":10,"timestamp":3 },
我需要得到 结果(ts=3) = (10-5)/(3-2).
在 elasticsearch 中有什么方法可以做到这一点吗?
我尝试以这种形式编写自己的指标脚本:
GET test1/_search
{
"size":15,
"aggs":{
"sum_the_hard_way": {
"scripted_metric": {
"init_script": {
"source": "state.values = []; state.timestamps = [];"
},
"map_script": {
"source": "state.values.add(doc['value'].value);state.timestamps.add(doc['timestamp'].value);"
},
"combine_script": {
"source": "def rates = []; for ( int i = 0; i <= state.values.size()-1 ; i++ ) { rate[i+1] = (state.value[i+1]- state.value[i])/(state.timestamp[i+1]- state.timestamp[i]);} return values"
},
"reduce_script": {
"source": "def vals = []; for (a in states) { vals.add(a) } return vals"
}
}
}
}
}
但是不行,我得到了
"reason" : "index_out_of_bounds_exception: Index 0 out of bounds for length
提前致谢!
TLDR;
某些类型滑入了您的代码。 希望我已经修好了。
GET /so_agg_painless/_search
{
"size":15,
"aggs":{
"sum_the_hard_way": {
"scripted_metric": {
"init_script": {
"source": """
state.values = [];
state.timestamps = [];
"""
},
"map_script": {
"source": """
state.values.add(doc['value'].value);
state.timestamps.add(doc['timestamp'].value);
"""
},
"combine_script": {
"source": """
def rates = [];
for ( int i = 0; i <= state.values.size()-2 ; i++ ) {
def nom = (state.values[i+1]- state.values[i]);
def denom = (state.timestamps[i+1]- state.timestamps[i]);
rates.add(nom/denom);
}
return rates
"""
},
"reduce_script": {
"source": """
def vals = [];
for (a in states) {
vals.add(a)
}
return vals
"""
}
}
}
}
}
嘿伙计,你的代码中有很多拼写错误,这就是它失败的原因。 但我认为逻辑是完美的,所以对你表示敬意,所以我们非常接近。
您需要注意代码中的那些s
。
也正如您在我发布的代码中看到的那样。使用 """
。所以你可以缩进代码,这样更容易阅读和修复。