1

Here is the my code:

const convertCurrency = async (currrencyType)  => {
    try{
        const res =  await got("https://api.exchangerate-api.com/v4/latest/USD");
        return (JSON.parse(res.body)['rates'][currrencyType]);
    }
    catch(err){
        console.log(err);
    }
}

async function search(){
  try{
    client.search({
      index : '03776182',
      body: {
        aggs : {
          price_ranges : {
              range : {
                  field : "price",
                  script : {source : "convertCurrency(/EUR/) * _value"},
                  ranges : [
                      { "from" : 10, "to" : 20 },
                  ]
              }
          }
      }
      }
  },(err,resp,status)=>{
      err ? console.log(err): console.log(JSON.stringify(resp));
  });
  }
  catch(err){console.log(err);}
}

I am trying to insert the custom script inside the source field. But it gives below error.

 response: `{"error":{"root_cause":[{"type":"script_exception","reason":"compile error","script_stack":["convertCurrency(/EUR/) * _value","                ^---- HERE"],"script":"convertCurrency(/EUR/) * _value","lang":"painless"}],"type":"search_phase_execution_exception","reason":"all shards failed","phase":"query","grouped":true,"failed_shards":[{"shard":0,"index":"03776182","node":"C4p_ha96QhK2uB47jV9pxg","reason":{"type":"script_exception","reason":"compile error","script_stack":["convertCurrency(/EUR/) * _value","                ^---- HERE"],"script":"convertCurrency(/EUR/) * _value","lang":"painless","caused_by":{"type":"illegal_state_exception","reason":"Regexes are disabled. Set [script.painless.regex.enabled] to [true] in elasticsearch.yaml to allow them. Be careful though, regexes break out of Painless's protection against deep recursion and long loops."}}}]},"status":500}`,
  toString: [Function],

At the same time normal expression are working well.

1 Answer 1

1

You cannot invoke a JS callback from an ES script, it doesn't make sense as they don't execute in the same context.

What you should do is to first retrieve the EUR exchange rate in your Node.js code and then send your query with that exchange rate as a parameter to your script.

In pseudo code, it would look like this:

// 1. retrieve EUR/USD exchange rate
const EUR_USD = convertCurrency('EUR');

// 2. send your query
client.search({
  index : '03776182',
  body: {
    aggs : {
      price_ranges : {
          range : {
              field : "price",
              script : {
                 source : "params.rate * _value"
                 params: { 
                    rate: EUR_USD
                 }
              },
              ranges : [
                  { "from" : 10, "to" : 20 },
              ]
          }
      }
  }
  }
Sign up to request clarification or add additional context in comments.

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.