在使用elasticsearch脚本指标统计时,出现了异常:
脚本:
POST account_test/_search?size=0
{
"query": {
"match_all": {}
},
"aggs": {
"balance_positive_sum": {
"scripted_metric": {
"init_script": "state.balances=[]",
"map_script": "if(doc.balance > 0){state.balances.add( doc.balance)}",
"combine_script": "double balanceSum=0;for(num in state.balances){balanceSum+=num} return balanceSum ",
"reduce_script": "double balanceSum=0;for(num in states){balanceSum+=num} return balanceSum"
}
}
}
}
异常:
{
"error": {
"root_cause": [
{
"type": "class_cast_exception",
"reason": "class_cast_exception: Cannot apply [>] operation to types [org.elasticsearch.index.fielddata.ScriptDocValues.Doubles] and [java.lang.Integer]."
}
],
"type": "search_phase_execution_exception",
"reason": "all shards failed",
"phase": "query",
"grouped": true,
"failed_shards": [
{
"shard": 0,
"index": "account_test",
"node": "cdYh0ptNTP6kMXlVSE8dqA",
"reason": {
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"if(doc.balance > 0){",
" ^---- HERE"
],
"script": "if(doc.balance > 0){state.balances.add( doc.balance)}",
"lang": "painless",
"caused_by": {
"type": "class_cast_exception",
"reason": "class_cast_exception: Cannot apply [>] operation to types [org.elasticsearch.index.fielddata.ScriptDocValues.Doubles] and [java.lang.Integer]."
}
}
}
],
"caused_by": {
"type": "class_cast_exception",
"reason": "class_cast_exception: Cannot apply [>] operation to types [org.elasticsearch.index.fielddata.ScriptDocValues.Doubles] and [java.lang.Integer]."
}
},
"status": 400
}
原因是在脚本中balance对应的类型是ScriptDocValues.Doubles,也就是封装类型,能直接执行>、<、=等操作,需要转原始类型。
解决办法:
调用getValue()
方法或者原始值。
POST account_test/_search?size=0
{
"query": {
"match_all": {}
},
"aggs": {
"balance_positive_sum": {
"scripted_metric": {
"init_script": "state.balances=[]",
"map_script": "if(doc.balance.getValue() > 0){state.balances.add( doc.balance.getValue())}",
"combine_script": "double balanceSum=0;for(num in state.balances){balanceSum+=num} return balanceSum ",
"reduce_script": "double balanceSum=0;for(num in states){balanceSum+=num} return balanceSum"
}
}
}
}
更多方法参考:ScriptDocValues.Doubles Java Doc。