简体   繁体   中英

Elasticsearch - Script filter on array

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:

  1. Your script just goes over a collection and checks a condition, doesn't return a boolean value, and that's what you want
  2. you might consider changing the mapping for number into an integer type
  3. not really sure why you have a field array and inside it a nested field key . Couldn't you just have a field array that would be... and array? ;-)
  4. remember that in ES by default each field can be a single value or an array.
  5. As @Val has mentioned you need to enable dynamic scripting in your 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
               ]
            }
         }
      ]
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM