Can I pass two sets of values to the reduce script?

Hi all,

I'm preparing an scripted metric in order to perform the division of two sums and display it in a Scripted Metric in Kibana (average viewing hours per user).

The problem I'm facing is that I need to perform the final division in the reduce part (the combine computes the partial sums, but I cannot perform partial divisions and then do something with them in the reduce script... this does not make sense for division I believe).

So, my question is: is there any way to pass two sets of values from the combine to the reduce by using the states variable? So far I manage to pass one of the partial sums, by returning "hours", or the other, by returning "users" but the idea would be for the reduce to be able to access both, and then perform the final sums and division.

This is my code:

{
"params": {
  "_agg": {}
},
"init_script": "state.views = []; state.docus = []",
"map_script": "state.views.add(doc.view_duration.value); state.docus.add(doc.channel_number.value)",
"combine_script": "double hours = 0; double users= 0; double resultado = 0; for (t in state.views) { hours += t} for (c in state.docus) { users +=1 } resultado = hours/users ; return hours",
"reduce_script": "double finalresult= 0; for (a in states) {finalresult+= a } return finalresult"
}

I would like to change the return in the combine script to return hours and users (returning "resultado" is useless because a partial division is not relevant to the final division). And the code in the reduce script to do somethig useful, because right now I can just operate on one of the partial sums, adding up the total, but I cannot make a division because I cannot access the other partial data.

Can the combine script return two values instead of one? And how would I access that from the reduce though the states variable?

Thanks!

Hi!

I managed to do this myself, so adding it here in case someone find this useful.
The following code computes the partial sums of hours and users, passes both values to the reduce script, and the reduce script then computes the final sums and resulting ratio:

{
"params": {
  "_agg": {}
},
"init_script": "state.views = []; state.users = []",
"map_script": "state.views.add(doc.view_duration.value); state.users.add(doc.channel_number.value)",
"combine_script": "double hours = 0; double users= 0; for (t in state.views) { hours += t} for (c in state.users) { users +=1 } double[] hours_users = new double[] {hours,users}; return hours_users", 
"reduce_script": "double hours= 0; double users= 0; double ratio= 0; for (a in states) { hours+= a[0]; users+= a[1] } ratio = hours/users; return ratio"
}

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.