I have a creeping suspicion that there is something very wrong with me putting a scripted metric inside a filter aggregation inside a terms aggregation.
Here is an example of the type of query that's giving me weird behavior.
{
"size": 0,
"aggs": {
"a": {
"terms": {
"field": "id",
"size": 10
},
"aggs": {
"measure" : {
"filter" : {
"bool" : {
"must" : [
{
"terms" : {
"foo.bar" : [
"foo"
],
"boost" : 1.0
}
},
{
"terms" : {
"foo.baz" : [
"bar"
],
"boost" : 1.0
}
}
]
}
},
"aggregations" : {
"profit": {
"scripted_metric": {
"init_script" : "params._agg.transactions = []",
"map_script" : "params._agg.transactions.add(1)",
"combine_script" : "double profit = 0; for (t in params._agg.transactions) { profit += t } return profit",
"reduce_script" : "double profit = 0; for (a in params._aggs) { profit += a } return profit"
}
}
}
}
}
}
}
}
At first glance nothing wrong here. Not super complicated its just the example scripted metric inside a filter aggregation inside a terms aggregation.
But the script will through a null pointer in the reduce script!
"caused_by": {
"type": "script_exception",
"reason": "runtime error",
"script_stack": [
"profit += a } ",
"^---- HERE"
],
"script": "double profit = 0; for (a in params._aggs) { profit += a } return profit",
"lang": "painless",
"caused_by": {
"type": "null_pointer_exception",
"reason": null
}
}
When debugging this it looks like the reduce script is running TWICE!
If I change the reduce_script to
"reduce_script" : "Debug.explain(params._aggs)"
I get back
"to_string": "[null]",
"java_class": "java.util.ArrayList",
"script_stack": [
"Debug.explain(params._aggs); double ",
" ^---- HERE"
]
Whats even more crazy is that if I change the reduce script to
"reduce_script" : "if (params._aggs[0] != null) {Debug.explain(params._aggs)}"
I get
"to_string": "[0.0]",
"java_class": "java.util.ArrayList",
"script_stack": [
"Debug.explain(params._aggs)}",
" ^---- HERE"
],
"script": "if (params._aggs[0] != null) {Debug.explain(params._aggs)}",
What's going on here? Why do I get two different values? And why is the script returning a [null] in the first place?