2018-07-02 17:44:36 -04:00
|
|
|
[[painless-watcher-transform-context]]
|
|
|
|
=== Watcher transform context
|
|
|
|
|
2019-01-14 21:44:21 -05:00
|
|
|
Use a Painless script as a {xpack-ref}/transform-script.html[watch transform]
|
|
|
|
to transform a payload into a new payload for further use in the watch.
|
|
|
|
Transform scripts return an Object value of the new payload.
|
2018-07-02 17:44:36 -04:00
|
|
|
|
2019-01-14 21:44:21 -05:00
|
|
|
include::painless-watcher-context-variables.asciidoc[]
|
2018-07-02 17:44:36 -04:00
|
|
|
|
2019-01-14 21:44:21 -05:00
|
|
|
*Return*
|
2018-07-02 17:44:36 -04:00
|
|
|
|
2019-01-14 21:44:21 -05:00
|
|
|
`Object`::
|
|
|
|
The new payload.
|
2018-07-02 17:44:36 -04:00
|
|
|
|
2019-01-14 21:44:21 -05:00
|
|
|
*API*
|
2018-07-02 17:44:36 -04:00
|
|
|
|
2019-01-14 21:44:21 -05:00
|
|
|
The standard <<painless-api-reference, Painless API>> is available.
|
2018-07-02 17:44:36 -04:00
|
|
|
|
2019-01-14 21:44:21 -05:00
|
|
|
*Example*
|
2018-07-02 17:44:36 -04:00
|
|
|
|
2019-08-16 11:32:18 -04:00
|
|
|
[source,js]
|
2019-01-14 21:44:21 -05:00
|
|
|
----
|
|
|
|
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" }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"transform" : {
|
|
|
|
"script":
|
|
|
|
"""
|
|
|
|
return [
|
|
|
|
'money_makers': ctx.payload.aggregations.theatres.buckets.stream() <1>
|
|
|
|
.filter(t -> { <2>
|
|
|
|
return t.money.value > 50000
|
|
|
|
})
|
|
|
|
.map(t -> { <3>
|
|
|
|
return ['play': t.key, 'total_value': t.money.value ]
|
|
|
|
}).collect(Collectors.toList()), <4>
|
|
|
|
'duds' : ctx.payload.aggregations.theatres.buckets.stream() <5>
|
|
|
|
.filter(t -> {
|
|
|
|
return t.money.value < 15000
|
|
|
|
})
|
|
|
|
.map(t -> {
|
|
|
|
return ['play': t.key, 'total_value': t.money.value ]
|
|
|
|
}).collect(Collectors.toList())
|
|
|
|
]
|
|
|
|
"""
|
|
|
|
},
|
|
|
|
"actions" : {
|
|
|
|
"my_log" : {
|
|
|
|
"logging" : {
|
|
|
|
"text" : "The output of the payload was transformed to {{ctx.payload}}"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
----
|
2019-08-16 11:32:18 -04:00
|
|
|
// CONSOLE
|
|
|
|
// TEST[skip: requires setup from other pages]
|
2018-07-02 17:44:36 -04:00
|
|
|
|
2019-01-14 21:44:21 -05:00
|
|
|
<1> The Java Stream API is used in the transform. 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> The stream map transforms each element into a new object.
|
|
|
|
<4> The collector reduces the stream to a `java.util.List`.
|
|
|
|
<5> This is done again for the second set of values in the transform.
|
2018-07-02 17:44:36 -04:00
|
|
|
|
2019-01-14 21:44:21 -05:00
|
|
|
The following action transform changes each value in the mod_log action into a `String`.
|
|
|
|
This transform does not change the values in the unmod_log action.
|
2018-07-02 17:44:36 -04:00
|
|
|
|
2019-08-16 11:32:18 -04:00
|
|
|
[source,js]
|
2019-01-14 21:44:21 -05:00
|
|
|
----
|
|
|
|
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" }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"actions" : {
|
|
|
|
"mod_log" : {
|
|
|
|
"transform": { <1>
|
|
|
|
"script" :
|
|
|
|
"""
|
|
|
|
def formatter = NumberFormat.getCurrencyInstance();
|
|
|
|
return [
|
|
|
|
'msg': ctx.payload.aggregations.theatres.buckets.stream()
|
|
|
|
.map(t-> formatter.format(t.money.value) + ' for the play ' + t.key)
|
|
|
|
.collect(Collectors.joining(", "))
|
|
|
|
]
|
|
|
|
"""
|
|
|
|
},
|
|
|
|
"logging" : {
|
|
|
|
"text" : "The output of the payload was transformed to: {{ctx.payload.msg}}"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"unmod_log" : { <2>
|
|
|
|
"logging" : {
|
|
|
|
"text" : "The output of the payload was not transformed and this value should not exist: {{ctx.payload.msg}}"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
----
|
2019-08-16 11:32:18 -04:00
|
|
|
// CONSOLE
|
|
|
|
// TEST[skip: requires setup from other pages]
|
2018-07-02 17:44:36 -04:00
|
|
|
|
2019-01-14 21:44:21 -05:00
|
|
|
This example uses the streaming API in a very similar manner. The differences below are
|
|
|
|
subtle and worth calling out.
|
2018-07-02 17:44:36 -04:00
|
|
|
|
2019-01-14 21:44:21 -05:00
|
|
|
<1> The location of the transform is no longer at the top level, but is within
|
|
|
|
an individual action.
|
|
|
|
<2> A second action that does not transform the payload is given for reference.
|
|
|
|
|
|
|
|
The following example shows scripted watch and action transforms within the
|
|
|
|
context of a complete watch. This watch also uses a scripted
|
|
|
|
<<painless-watcher-condition-context, condition>>.
|
2018-07-02 17:44:36 -04:00
|
|
|
|
2019-01-14 21:44:21 -05:00
|
|
|
include::painless-watcher-context-example.asciidoc[]
|