1

I am using a painless script to implement a custom scoring function while querying the ES index, that's being used as a basis for our recommendation engine. While calculating the final score in the painless script, I use a product of intermediate variables such as recency and uniqueness, calculated within the painless script.

Now, it is trivial to get the final scores of the top documents as they are returned within the query response. However, for detailed analysis, I'm trying to find a way to also get the intermediate variables' values (recency and uniqueness as in the above example). I understand these painless variables only exist within the context of the painless script, which does not have standard REPL setup. So is there really no way to access these painless variables? Has anyone found a workaround to do this? Thanks!

E.g. If I have the following simplified painless script:

def recency = 1/doc['date'].value
def uniqueness = doc['ctr].value

return recency * uniqueness

In the final ES response, I get the scores i.e. recency * uniqueness. However, I also want to know what the intermediate variables are i.e. recency and uniqueness

2 Answers 2

1

You can try using a modular approach with multiple scripted fields like:

  1. recency -- get the recency field
  2. uniqueness -- get the uniqueness field

  3. access the fields like a normal ES field in your final painless script

if(doc.containsKey('recency.keyword') && doc.containsKey('uniqueness.keyword'))
{
  def val1 = doc['recency.keyword'].value;
  def val2 = doc['uniqueness.keyword'].value;
}

Hope it helps

Sign up to request clarification or add additional context in comments.

4 Comments

thanks for response aritra! It doesn't solve the issue so I think I was unclear in my question - I've added a clear example so hopefully it will help! Thanks
well my suggestion still holds true if you do not mind having 3 scripted fields instead of one. However, if you really want to have just a single field - you may try to return a map ... ``` def recency = 1/doc['date'].value def uniqueness = doc['ctr].value def result = recency * uniqueness def returnMap = ['recency': recency, 'uniqueness': uniqueness, 'result': result] ```
so I tried using script fields and obtain the following fields in the result fields': {'recency': [5669752], 'uniqueness': [8504628.0]} But now I can't access them in my final painless script. I tried using your method but it doesn't work for me. Do I to create separate mappings for recency and uniqueness in my index prior?
Also, referring to your returning map solution, how can you return a map in a painless script since the script is expecting a single score to sort on?
0

There is not direct way of printing it anywhere i suppose. But here is what you can give it a try to check the intermediate output of any variable.

  • create another scripted field which will return only the value of that variable.

For Ex: in your case,

"script_fields": {
"derivedRecency": {
      "script": {
        "lang": "painless",
        "source": """ 
            return doc['recency'].value;
            
          """
      }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.