Search code examples
elasticsearchscriptingelasticsearch-painless

ElasticSearch/Painless: How do I skip an item when iterating?


I have a for loop that iterates a list. If the list contains a certain value, say "5", I want the loop to skip that value. But Painless seems determined to not permit that by not letting me have an empty if block or use a continue statement. How can I accomplish this?

"script_fields": {
"HResultCount": {
  "script": {
    "lang": "painless",
    "inline": "int instance = 0; for (int i = 0; i < doc['numbers'].length; ++i) { if (doc['numbers'] == '5') { /* bail out */ } else { return 1.0; } }" 
  }
}

Solution

  • Since a script has to return a value in all cases, you can remove the value 5 from the list before iterating as you suggested.

    You can achieve this like that by calling removeIf on a copy of your list with a Java 8 lambda:

    "script_fields": {
    "HResultCount": {
      "script": {
        "lang": "painless",
        "inline": "int instance = 0; List copy = new ArrayList(doc['numbers']); copy.removeIf(i -> i == 5); for (int i = 0; i < copy.length; ++i) { instance += copy[i]; } return instance;" 
      }
    }