Elasticsearch script query get parameter by field value

3.3k views Asked by At

I am trying to filter results with script query. I can access parameter values with hardcoded field value like this:

"script": "doc['price'].value * params.1000 > 4000",
      "params": {"1000": "1.75"}

But if I try to get field value with doc there is no filtering and I can see all results.

    "script": "doc['price'].value * params.doc['rate'] > 4000",
      "params": {"1000": "1.75"}

Is there any solution to dynamically get parameter value?

EDIT:

The Field 'rate' is just the ID. It is Integer but it is not value I need. The idea is to pass every time different value, via parameter, instead updating field 'rate' frequently. Hope This is better explanation...

example:

"script": "doc['price'].value * params.doc['rate'] > 4000",
  "params": {
              "1000": "1.75",
              "1001": "3.75",
              "1002": "5"
            }

if 
'price' == 10 &&
'rate' == 1002
result should be: 10 * 5 > 4000  

if 
'price' == 10 &&
'rate' == 1001
result should be: 10 * 3.75 > 4000

if 
'price' == 7 &&
'rate' == 1000
result should be: 7 * 1.75 > 4000   
3

There are 3 answers

1
Kulasangar On

I'm assuming rate as an integer, if so shouldn't the script look like such. If I've understood your filtering correctly, if not please correct me:

 "script": "(doc['price'].value * doc['rate'].value) > 4000", <--replace params with doc
      "params": {"1000": "1.75"}
0
Ashutosh Bhardwaj On

Had a similar use case, you can do it like this.

"script": {
             "source": "if (params.containsKey(doc['id'].value)) { return params[doc['id'].value] } else { return 0 }",
             "params": {
              "60378": 10.0,
              "50236": 5.0,
              "51233": 3.33
            }
          }

Writing an if check before accessing the param value makes it safe query, otherwise it will break with script exception.

0
Tomassino Ferrauto On

You can try with something like this:

"script": {
    "lang": "painless",
    "inline": "doc['price'].value * params.get(doc['rate'].toString()) > 4000",
    "params": {
        "[1000]": 1.75,
        "[1001]": 3.75,
        "[1002]": 5
    }
}

Why parameters need square brackets I don't know, but using a script with Debug.explain(doc['rate'].toString()) shows that the rate field converted to string is like that (perhaps you can use a keyword field for rate, in that case I suppose parameters can have the exact same name as the field value):

"error": {
    "caused_by": {
        "reason": null,
        "type": "painless_explain_error"
    },
    "class": "java.lang.String",
    "lang": "painless",
    ...
    "script": "Debug.explain(doc['rate'].toString())",
    ...
    "to_string": "[1000]",
},
...

I have used params.get is because params is an HashMap (again, found using Debug.explain(params)). Also parameters values are not strings.