Easysearch、Elasticsearch 还是 Opensearch,是个问题

es5.5版本,date_histogram聚合嵌套scripted_metric聚合,报错

Elasticsearch | 作者 王社英 | 发布于2019年01月10日 | 阅读数:3061

es中有4条数据,index是netelement,type是kpi
time,a,b,c,d
2018-11-04 09:00:00,1,2,3,4
2018-11-04 12:00:00,5,6,7,8
2018-11-05 15:00:00,11,12,13,14
2018-11-05 17:00:00,15,16,17,18

现在需要计算一天内的kpi
计算公式是总和 (a+b)/(c+d)
比如
在2018-11-04,这一天内,就是
(1+2+5+6)/(3+4+7+8)
在2018-11-05,这一天内,就是
(11+12+15+16)/(13+14+17+18)

现在我写的aggs是,但是运行报错
POST /netelement/kpi/_search
{
"aggs": {
"kpi": {
"date_histogram": {
"field": "time",
"interval": "1d"
},
"aggs": {
"kpi": {
"scripted_metric": {
"init_script": "params._agg['subtract'] = [] ",
"map_script": "params._agg.subtract.add([doc.a.value + doc.b.value,doc.c.value + doc.d.value])",
"combine_script": "double total1=0;double total2=0; for (i in params._agg.subtract) { total1 += i[0]; total2 += i[1] } return [total1, total2]",
"reduce_script": "double total1=0; double total2=0; for (item in params._aggs) { total1 += item[0]; total2 += item[1]} return total1 / total2"
}
}
}
}
}
}

错误信息如下
{
"error": {
"root_cause": ,
"type": "search_phase_execution_exception",
"reason": "",
"phase": "fetch",
"grouped": true,
"failed_shards": ,
"caused_by": {
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"total1 += item[0]; ",
"^---- HERE"
],
"script": "double total1=0; double total2=0; for (item in params._aggs) { total1 += item[0]; total2 += item[1]} return total1 / total2",
"lang": "painless",
"caused_by": {
"type": "null_pointer_exception",
"reason": null
}
}
},
"status": 503
}
已邀请:

God_lockin

赞同来自: 王社英

 
改了两个地方:
1. init_script 里面加了个初始化,直接一个等号在那里直接编译错误
2. reduce_script 里加了
if (null == item) continue;

 nullpoint 说的是 i 是 null,不是total1、total2是null,应该是和迭代器有关,目前还没在代码里找到原因,但是somehow迭代出来一个null出来,把它跳过就好了
{
"aggs": {
"kpi": {
"date_histogram": {
"field": "time",
"interval": "1d"
},
"aggs": {
"kpi": {
"scripted_metric": {
"init_script": "params._agg['subtract'] = new ArrayList()",
"map_script": "params._agg.subtract.add([doc.a.value + doc.b.value,doc.c.value + doc.d.value])",
"combine_script": "double total1=0;double total2=0; for (i in params._agg.subtract) { total1 += i[0]; total2 += i[1] } return [total1, total2]",
"reduce_script": "double total1=0; double total2=0; for (item in params._aggs) { if (null == item) continue; total1 += item[0]; total2 += item[1]} return total1 / total2"
}
}
}
}
}
}

rochy - rochy_he

赞同来自: 王社英

还有一种实现的方法:
在 date_histogram 聚合下面新建 4 个 Sum 聚合,分别计算 a,b,c,d 的 sum;
然后在最后添加一个 bucket_script 直接求取 ( sum(a) + sum(b) ) / ( sum(c) + sum(d) )

要回复问题请先登录注册