Dynamic code evaluation using Script

I have a field in Elastic search of type 'keyword' with value = "Quantity <= 10".
"hits": [
{
"_index": "rules1",
"_type": "_doc",
"_id": "zvMleGoBkFxQI52IVKGV",
"_score": 1,
"_source": {
"id": "1",
"criteria1": "Quantity <= 10"
}
},
{
"_index": "rules1",
"_type": "_doc",
"_id": "z_MleGoBkFxQI52ItqFC",
"_score": 1,
"_source": {
"id": "2",
"criteria1": "Quantity <= 20"
}
}
]

I need to filter documents with passing Quantity as one of the parameters. I was using painless script -

{
"query": {
    "bool" : {
        "filter" : {
            "script" : {
                "script" : {
                    "source" : "doc['criteria1'].value",
                    "lang"   : "painless",
                    "params" : {
                        "Quantity" : "5"
                    }
                }
            }
        }
    }
}

}

But it is giving an error -

{
"error": {
    "root_cause": [
        {
            "type": "script_exception",
            "reason": "runtime error",
            "script_stack": [
                "doc['criteria1'].value",
                "                ^---- HERE"
            ],
            "script": "doc['criteria1'].value",
            "lang": "painless"
        }
    ],
    "type": "search_phase_execution_exception",
    "reason": "all shards failed",
    "phase": "query",
    "grouped": true,
    "failed_shards": [
        {
            "shard": 0,
            "index": "rules1",
            "node": "bYDoLP0hSUuOcp9eEriIqQ",
            "reason": {
                "type": "script_exception",
                "reason": "runtime error",
                "script_stack": [
                    "doc['criteria1'].value",
                    "                ^---- HERE"
                ],
                "script": "doc['criteria1'].value",
                "lang": "painless",
                "caused_by": {
                    "type": "class_cast_exception",
                    "reason": "cannot cast def [java.lang.String] to boolean"
                }
            }
        }
    ]
},
"status": 400

}

You need to convert that into a boolean expression, like doc['criteria1'].value > params.Quantity

Hi @polyfractal . Thank you for your reply. Actually, I already have an expression in the field 'criteria1'.
Example: "criteria1":"Quantity <= 10"

Now, I want to write a elastic search query in such a way that if I pass Quantity as a param in the query, it will replace that value in criteria1 field and evaluate it to a boolean. (Sort of rule evaluation to a boolean value with a dynamic value).

Example: If I pass Quantity = 5 to criteria1, the document will be retrieved, else if Quantity = 15, the document will not be retrieved.

Yep, you need to prefix the variable with params, e.g. params.Quantity :slight_smile:

I tried but it is not working as expected. Again trying to explain my problem statement -

@polyfractal these are 2 sample documents -
{
"_index": "rules1",
"_type": "_doc",
"_id": "0fOxkWoBkFxQI52IgKFf",
"_score": 1,
"_source": {
"id": "4",
"criteria1": "Quantity <= 5"
}
},
{
"_index": "rules1",
"_type": "_doc",
"_id": "zvMleGoBkFxQI52IVKGV",
"_score": 1,
"_source": {
"id": "1",
"criteria1": "Quantity <= 10"
}
}

Can you please help me with a query where I pass Quantity to the query.
If Quantity = 3, both id = 1 and id = 4 are retrieved.
If Quantity = 7, only id = 1 is retrieved.

1 Like

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