[[painless-watcher-condition-context]]
=== Watcher condition context

Use a Painless script as a {ref}/condition-script.html[watch condition]
that determines whether to execute a watch or a particular action within a watch.
Condition scripts return a Boolean value to indicate the status of the condition.

include::painless-watcher-context-variables.asciidoc[]

*Return*

`boolean`::
        Expects `true` if the condition is met, and `false` if it is not.

*API*

The standard <<painless-api-reference, Painless API>> is available.

*Example*

To run the examples, first follow the steps in
<<painless-context-examples, context examples>>.

[source,console]
----
POST _watcher/watch/_execute
{
  "watch" : {
    "trigger" : { "schedule" : { "interval" : "24h" } },
    "input" : {
      "search" : {
        "request" : {
          "indices" : [ "seats" ],
          "body" : {
            "query" : {
              "term": { "sold": "true"}
            },
            "aggs" : {
              "theatres" : {
                "terms" : { "field" : "play" },
                "aggs" : {
                  "money" : {
                    "sum": { "field" : "cost" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "condition" : {
      "script" :
      """
        return ctx.payload.aggregations.theatres.buckets.stream()       <1>
          .filter(theatre -> theatre.money.value < 15000 ||
                             theatre.money.value > 50000)               <2>
          .count() > 0                                                  <3>
      """
    },
    "actions" : {
      "my_log" : {
        "logging" : {
          "text" : "The output of the search was : {{ctx.payload.aggregations.theatres.buckets}}"
        }
      }
    }
  }
}
----
// TEST[setup:seats]

<1> The Java Stream API is used in the condition. This API allows manipulation of
the elements of the list in a pipeline.
<2> The stream filter removes items that do not meet the filter criteria.
<3> If there is at least one item in the list, the condition evaluates to true and the watch is executed.

The following action condition script controls execution of the my_log action based
on the value of the seats sold for the plays in the data set. The script aggregates
the total sold seats for each play and returns true if there is at least one play
that has sold over $10,000.

[source,console]
----
POST _watcher/watch/_execute
{
  "watch" : {
    "trigger" : { "schedule" : { "interval" : "24h" } },
    "input" : {
      "search" : {
        "request" : {
          "indices" : [ "seats" ],
          "body" : {
            "query" : {
              "term": { "sold": "true"}
            },
            "size": 0,
            "aggs" : {
              "theatres" : {
                "terms" : { "field" : "play" },
                "aggs" : {
                  "money" : {
                    "sum": {
                      "field" : "cost",
                      "script": {
                       "source": "doc.cost.value * doc.number.value"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "actions" : {
      "my_log" : {
        "condition": {                                                <1>
          "script" :
          """
            return ctx.payload.aggregations.theatres.buckets.stream()
              .anyMatch(theatre -> theatre.money.value > 10000)       <2>
          """
        },
        "logging" : {
          "text" : "At least one play has grossed over $10,000: {{ctx.payload.aggregations.theatres.buckets}}"
        }
      }
    }
  }
}
----
// TEST[setup:seats]

This example uses a nearly identical condition as the previous example. The
differences below are subtle and are worth calling out.

<1> The location of the condition is no longer at the top level, but is within
an individual action.
<2> Instead of a filter, `anyMatch` is used to return a boolean value
