Lev Lev - 1 year ago 119
Groovy Question

Elasticsearch groovy script to check parameter inclusion in array

I'm using elasticsearch (v2.0.0) for search in Rails and want to add to our custom script for scoring, but I'm either messing up the syntax or just missing something else entirely. It all works without the check in the script for the array, so that's the only part that's not working.

So for the index,

is an array of integers:

indexes :recipe_user_ids, type: 'integer'

Then in the search query I specify the parameter for the script file and which script file:

functions: [{
script_score: {
params: { current_user_id: user.id },
script_file: 'ownership_script'

And the ownership-script.groovy file:

if (current_user_id == doc['user_id'].value) { owner_modifier = 1.0 } else { owner_modifier = 0.0 }
if (doc['recipe_user_ids'].values.contains(current_user_id)) { recipe_user_modifier = 50.0 } else { recipe_user_modifier = 0.0 }
(_score + (doc['score_for_sort'].value + owner_modifier + recipe_user_modifier)*5)/_score

I'm not getting any errors, but the results don't seem to match what I'd expect when the
array does contain
, so everything is falling into the else statement. Is it a type issue, syntax? Any tips greatly appreciated.

Answer Source

This seems to occur due to mismatch in type caused by autoboxing.

The doc['field_name].values for field mapping short, integer, long types seems to be returning a collection always of type 'Long' and the argument to contains is autoboxed to Integercausing contains to fail.

You could probably explictly cast current_user_id to the type of Long:


doc['recipe_user_ids'].values.contains(new Long(current_user_id))

Or better to use the 'find' method

doc['recipe_user_ids'].values.find {it == current_user_id}