I'm a new bie in ES and I want to use script filter to get all match that the array has at least one element less than max and greater than min (max and min are param in the script).
The document like:
{
"number": "5",
"array": {
"key": [
10,
5,
9,
20
]
}
}
I tried the script but it does not work
{
"script": {
"lang": "groovy",
"params": {
"max": 64,
"min": 6
},
"script": "for(element in doc['array.key'].values){element>= min + doc['number'].value && element <=max + doc['number'].value}"
}
}
There is no error message but the search result is wrong.Is there a way to iterate array field?
Thank you all.
Yes it's doable, your script is not doing that, though. Try using Groovy's any() method instead:
doc['array.key'].values.any{ it -> it >= min + doc['number'] && it <= max + doc['number'] }
A few things:
number into an integer typearray and inside it a nested field key. Couldn't you just have a field array that would be... and array? ;-)conf/elasticsearch.yml but I'm guessing you've done it, otherwise you'd be getting exceptions.A very simple mapping like this should work:
{
"mappings": {
"document": {
"properties": {
"value": {
"type": "integer"
},
"key": {
"type": "integer"
}
}
}
}
}
Example:
POST /documents/document/1
{
"number": 5,
"key": [
10,
5,
9,
20
]
}
POST /documents/document/2
{
"number": 5,
"key": [
70,
72
]
}
Query:
GET /documents/document/_search
{
"query": {
"bool": {
"filter": {
"script": {
"lang": "groovy",
"params": {
"max": 64,
"min": 6
},
"script": "doc['key'].values.any{ it -> it >= min + doc['number'] && it <= max + doc['number'] }"
}
}
}
}
}
Result:
{
"took": 22,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0,
"hits": [
{
"_index": "documents",
"_type": "document",
"_id": "1",
"_score": 0,
"_source": {
"number": 5,
"key": [
10,
5,
9,
20
]
}
}
]
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With