Skip to content

Commit

Permalink
[DOCS] [7.x] Update Painless examples to use seat data (#68029) (#68084
Browse files Browse the repository at this point in the history
…) (#68086)

* Adds datetime as a date, which is necessary in setup.

* Updating field context example.

* Fixing sample data, updating context example, and updating runtime example.

* Updating field context and changing runtime field to use seats data.

* Update filter context to use the seats data.

* Updating min-should-match context to use seats data.

* Replacing last mentions of TEST[skip].

* Update usage with watcher response for build error.

* Updating usage API again for watcher.

* Third time's a charm for fixing test cases.

* Adding specific test replacement for watcher logging total.

* Change actors to keyword based on review feedback.

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
Adam Locke and elasticmachine authored Jan 27, 2021
1 parent b0ebcd1 commit a1fbbdf
Show file tree
Hide file tree
Showing 11 changed files with 75 additions and 138 deletions.
7 changes: 5 additions & 2 deletions docs/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -1330,6 +1330,8 @@ setups['seats'] = '''
type: long
sold:
type: boolean
datetime:
type: date
- do:
raw:
Expand All @@ -1349,14 +1351,15 @@ setups['seats'] = '''
- do:
bulk:
index: seats
pipeline: seats
refresh: true
body: |
{"index":{"_id": "1"}}
{"theatre": "Skyline", "play": "Rent", "actors": ["James Holland", "Krissy Smith", "Joe Muir", "Ryan Earns"], "date": "2021-4-1", "time": "3:00PM", "cost": 37, "row": 1, "number": 7, "sold": false}
{"index":{"_id": "2"}}
{"theatre": "Graye", "play": "Rent", "actors": "Dave Christmas", "date": "2021-4-1", "time": "3:00PM", "cost": 30, "row": 3, "number": 5, "sold": false}
{"theatre": "Graye", "play": "Rent", "actors": ["Dave Christmas"], "date": "2021-4-1", "time": "3:00PM", "cost": 30, "row": 3, "number": 5, "sold": false}
{"index":{"_id": "3"}}
{"theatre": "Graye", "play": "Rented", "actors": "Dave Christmas", "date": "2021-4-1", "time": "3:00PM", "cost": 33, "row": 2, "number": 6, "sold": false}
{"theatre": "Graye", "play": "Rented", "actors": ["Dave Christmas"], "date": "2021-4-1", "time": "3:00PM", "cost": 33, "row": 2, "number": 6, "sold": false}
{"index":{"_id": "4"}}
{"theatre": "Skyline", "play": "Rented", "actors": ["James Holland", "Krissy Smith", "Joe Muir", "Ryan Earns"], "date": "2021-4-1", "time": "3:00PM", "cost": 20, "row": 5, "number": 2, "sold": false}
{"index":{"_id": "5"}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ Each document in the `seat` data contains the following fields:
The number of the seat within a row.
`sold` ({ref}/boolean.html[`boolean`])::
Whether or not the seat is sold.
`datetime` ({ref}/date.html[`date`])::
The date and time of the play as a date object.

==== Prerequisites
Start an {ref}/getting-started-install.html[{es} instance], and then access the
Expand All @@ -41,13 +43,14 @@ PUT /seats
"properties": {
"theatre": { "type": "keyword" },
"play": { "type": "keyword" },
"actors": { "type": "text" },
"actors": { "type": "keyword" },
"date": { "type": "keyword" },
"time": { "type": "keyword" },
"cost": { "type": "double" },
"row": { "type": "integer" },
"number": { "type": "integer" },
"sold": { "type": "boolean" }
"sold": { "type": "boolean" },
"datetime": { "type": "date" }
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions docs/painless/painless-contexts/painless-field-context.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ the `getDayOfWeek` function to determine the corresponding day of the week.

[source,Painless]
----
doc['datetime'].value.getDayOfWeek();
doc['datetime'].value.getDayOfWeekEnum();
----

The second script calculates the number of actors. Actors' names are stored
as a text array in the `actors` field.

[source,Painless]
----
params['_source']['actors'].length; <1>
params['_source']['actors'].size(); <1>
----

<1> By default, doc values are not available for text fields. However,
Expand All @@ -69,15 +69,15 @@ GET seats/_search
"script_fields": {
"day-of-week": {
"script": {
"source": "doc['datetime'].value.getDayOfWeek()"
"source": "doc['datetime'].value.getDayOfWeekEnum()"
}
},
"number-of-actors": {
"script": {
"source": "params['_source']['actors'].length"
"source": "params['_source']['actors'].size()"
}
}
}
}
----
// TEST[skip: requires setup from other pages]
// TEST[setup:seats]
12 changes: 6 additions & 6 deletions docs/painless/painless-contexts/painless-filter-context.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ The standard <<painless-api-reference, Painless API>> is available.
To run this example, first follow the steps in
<<painless-context-examples, context examples>>.

This script finds all unsold documents that cost less than $18.
This script finds all unsold documents that cost less than $25.

[source,Painless]
----
doc['sold'].value == false && doc['cost'].value < 18
doc['sold'].value == false && doc['cost'].value < 25
----

Defining cost as a script parameter enables the cost to be configured
Defining `cost` as a script parameter enables the cost to be configured
in the script query request. For example, the following request finds
all available theatre seats for evening performances that are under $18.
all available theatre seats for evening performances that are under $25.

[source,console]
----
Expand All @@ -52,7 +52,7 @@ GET seats/_search
"script": {
"source": "doc['sold'].value == false && doc['cost'].value < params.cost",
"params": {
"cost": 18
"cost": 25
}
}
}
Expand All @@ -61,4 +61,4 @@ GET seats/_search
}
}
----
// TEST[skip: requires setup from other pages]
// TEST[setup:seats]
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,14 @@ To run this example, first follow the steps in
Imagine that you want to find seats to performances by your favorite
actors. You have a list of favorite actors in mind, and you want
to find performances where the cast includes at least a certain
number of them. `terms_set` query with `minimum_should_match_script`
is a way to accomplish this. To make the query request more configurable,
number of them.

To achieve this result, use a `terms_set` query with
`minimum_should_match_script`. To make the query request more configurable,
you can define `min_actors_to_see` as a script parameter.

To ensure that the parameter `min_actors_to_see` doesn't exceed
the number of favorite actors, you can use `num_term`s to get
the number of favorite actors, you can use `num_terms` to get
the number of actors in the list and `Math.min` to get the lesser
of the two.

Expand Down Expand Up @@ -75,5 +77,4 @@ GET seats/_search
}
}
----
// TEST[skip: requires setup from other pages]

// TEST[setup:seats]
Original file line number Diff line number Diff line change
Expand Up @@ -33,94 +33,11 @@ Both the standard <<painless-api-reference-shared, Painless API>> and

*Example*

Let's break down each of the steps from the
<<painless-context-examples,context examples>> to understand how runtime fields
work within the context of Painless.
To run the examples, first follow the steps in
<<painless-context-examples, context examples>>.

[[painless-runtime-fields-mappings]]
==== Create the index mappings
First, create the mappings for the sample data:

[source,console]
----
PUT /seats
{
"mappings": {
"properties": {
"theatre": { "type": "keyword" },
"play": { "type": "keyword" },
"actors": { "type": "text" },
"row": { "type": "integer" },
"number": { "type": "integer" },
"cost": { "type": "double" },
"sold": { "type": "boolean" },
"datetime": { "type": "date" },
"date": { "type": "keyword" },
"time": { "type": "keyword" }
}
}
}
----

[[painless-runtime-fields-processor]]
==== Run the ingest processor
Next, run the request from the <<painless-ingest-processor-context,Painless ingest processor context>> to configure a script ingest processor that parses
each document as the `seat` data is indexed:

[source,console]
----
PUT /_ingest/pipeline/seats
{
"description": "update datetime for seats",
"processors": [
{
"script": {
"source": "String[] dateSplit = ctx.date.splitOnToken('-'); String year = dateSplit[0].trim(); String month = dateSplit[1].trim(); if (month.length() == 1) { month = '0' + month; } String day = dateSplit[2].trim(); if (day.length() == 1) { day = '0' + day; } boolean pm = ctx.time.substring(ctx.time.length() - 2).equals('PM'); String[] timeSplit = ctx.time.substring(0, ctx.time.length() - 2).splitOnToken(':'); int hours = Integer.parseInt(timeSplit[0].trim()); int minutes = Integer.parseInt(timeSplit[1].trim()); if (pm) { hours += 12; } String dts = year + '-' + month + '-' + day + 'T' + (hours < 10 ? '0' + hours : '' + hours) + ':' + (minutes < 10 ? '0' + minutes : '' + minutes) + ':00+08:00'; ZonedDateTime dt = ZonedDateTime.parse(dts, DateTimeFormatter.ISO_OFFSET_DATE_TIME); ctx.datetime = dt.getLong(ChronoField.INSTANT_SECONDS)*1000L;"
}
}
]
}
----
// TEST[continued]

[[painless-runtime-fields-ingest]]
==== Ingest some sample data
Use the ingest pipeline you defined to ingest some sample data. You
can ingest the full https://download.elastic.co/demos/painless/contexts/seats.json[seat sample data], but we'll only use a subset for this example:

[source,console]
----
POST seats/_bulk?pipeline=seats&refresh=true
{"create":{"_index":"seats","_id":"1"}}
{"theatre":"Down Port","play":"Driving","actors":["James Holland","Krissy Smith","Joe Muir","Ryan Earns"],"date":"2018-4-1","time":"3:00PM","row":1,"number":1,"cost":30,"sold":false}
{"create":{"_index":"seats","_id":"2"}}
{"theatre":"Down Port","play":"Driving","actors":["James Holland","Krissy Smith","Joe Muir","Ryan Earns"],"date":"2018-4-1","time":"3:00PM","row":1,"number":2,"cost":30,"sold":false}
{"create":{"_index":"seats","_id":"3"}}
{"theatre":"Down Port","play":"Driving","actors":["James Holland","Krissy Smith","Joe Muir","Ryan Earns"],"date":"2018-4-1","time":"3:00PM","row":1,"number":3,"cost":30,"sold":true}
{"create":{"_index":"seats","_id":"4"}}
{"theatre":"Down Port","play":"Driving","actors":["James Holland","Krissy Smith","Joe Muir","Ryan Earns"],"date":"2018-4-1","time":"3:00PM","row":1,"number":4,"cost":30,"sold":false}
{"create":{"_index":"seats","_id":"5"}}
{"theatre":"Down Port","play":"Driving","actors":["James Holland","Krissy Smith","Joe Muir","Ryan Earns"],"date":"2018-4-1","time":"3:00PM","row":1,"number":5,"cost":30,"sold":false}
{"create":{"_index":"seats","_id":"6"}}
{"theatre":"Down Port","play":"Driving","actors":["James Holland","Krissy Smith","Joe Muir","Ryan Earns"],"date":"2018-4-1","time":"3:00PM","row":1,"number":6,"cost":30,"sold":true}
{"create":{"_index":"seats","_id":"7"}}
{"theatre":"Down Port","play":"Driving","actors":["James Holland","Krissy Smith","Joe Muir","Ryan Earns"],"date":"2018-4-1","time":"3:00PM","row":1,"number":7,"cost":30,"sold":true}
{"create":{"_index":"seats","_id":"8"}}
{"theatre":"Down Port","play":"Driving","actors":["James Holland","Krissy Smith","Joe Muir","Ryan Earns"],"date":"2018-4-1","time":"3:00PM","row":1,"number":8,"cost":30,"sold":false}
{"create":{"_index":"seats","_id":"9"}}
{"theatre":"Down Port","play":"Driving","actors":["James Holland","Krissy Smith","Joe Muir","Ryan Earns"],"date":"2018-4-1","time":"3:00PM","row":1,"number":9,"cost":30,"sold":true}
{"create":{"_index":"seats","_id":"10"}}
{"theatre":"Down Port","play":"Driving","actors":["James Holland","Krissy Smith","Joe Muir","Ryan Earns"],"date":"2018-4-1","time":"3:00PM","row":1,"number":10,"cost":30,"sold":false}
{"create":{"_index":"seats","_id":"11"}}
{"theatre":"Down Port","play":"Driving","actors":["James Holland","Krissy Smith","Joe Muir","Ryan Earns"],"date":"2018-4-1","time":"3:00PM","row":1,"number":11,"cost":30,"sold":false}
{"create":{"_index":"seats","_id":"12"}}
----
// TEST[continued]

[[painless-runtime-fields-definition]]
==== Define a runtime field with a Painless script
Run the following request to define a runtime field named `day_of_week`. This
field contains a script with the same `source` defined in
Then, run the following request to define a runtime field named `day_of_week`.
This field contains a script with the same `source` defined in
<<painless-field-context,Field context>>, but also uses an `emit` function
that runtime fields require when defining a Painless script.

Expand All @@ -133,15 +50,15 @@ PUT seats/_mapping
{
"runtime": {
"day_of_week": {
"type": "date",
"type": "keyword",
"script": {
"source": "emit(doc['datetime'].value.getDayOfWeekEnum().getValue())"
"source": "emit(doc['datetime'].value.getDayOfWeekEnum().toString())"
}
}
}
}
----
// TEST[continued]
// TEST[setup:seats]

After defining the runtime field and script in the mappings, you can run a
query that includes a terms aggregation for `day_of_week`. When the query runs,
Expand Down Expand Up @@ -179,7 +96,7 @@ defined in the mappings.
...
"hits" : {
"total" : {
"value" : 11,
"value" : 10,
"relation" : "eq"
},
"max_score" : null,
Expand All @@ -191,14 +108,24 @@ defined in the mappings.
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : 7,
"key_as_string" : "1970-01-01T00:00:00.007Z",
"doc_count" : 11
"key" : "THURSDAY",
"doc_count" : 4
},
{
"key" : "TUESDAY",
"doc_count" : 4
},
{
"key" : "MONDAY",
"doc_count" : 1
},
{
"key" : "SUNDAY",
"doc_count" : 1
}
]
}
}
}
----
// TESTRESPONSE[s/\.\.\./"took" : $body.took,"timed_out" : $body.timed_out,"_shards" : $body._shards,/]
// TESTRESPONSE[s/"value" : "11"/"value": $body.hits.total.value/]
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ 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
Expand Down Expand Up @@ -65,7 +68,7 @@ POST _watcher/watch/_execute
}
}
----
// TEST[skip: requires setup from other pages]
// 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.
Expand Down Expand Up @@ -122,7 +125,7 @@ POST _watcher/watch/_execute
}
}
----
// TEST[skip: requires setup from other pages]
// TEST[setup:seats]

This example uses a nearly identical condition as the previous example. The
differences below are subtle and are worth calling out.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ POST _watcher/watch/_execute
}
}
----
// TEST[skip: requires setup from other pages]
// TEST[setup:seats]

The following example shows the use of metadata and transforming dates into a readable format.

Expand Down Expand Up @@ -156,4 +156,4 @@ POST _watcher/watch/_execute
}
}
----
// TEST[skip: requires setup from other pages]
// TEST[setup:seats]
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,3 @@ The following variables are available in all watcher contexts.
`ctx['payload']` (`Map`, read-only)::
The accessible watch data based upon the
{ref}/input.html[watch input].

*API*


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

To run this example, first follow the steps in
<<painless-context-examples, context examples>>.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ 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
Expand Down Expand Up @@ -75,7 +78,7 @@ POST _watcher/watch/_execute
}
}
----
// TEST[skip: requires setup from other pages]
// TEST[setup:seats]

<1> The Java Stream API is used in the transform. This API allows manipulation of
the elements of the list in a pipeline.
Expand Down Expand Up @@ -141,7 +144,7 @@ POST _watcher/watch/_execute
}
}
----
// TEST[skip: requires setup from other pages]
// TEST[setup:seats]

This example uses the streaming API in a very similar manner. The differences below are
subtle and worth calling out.
Expand Down
Loading

0 comments on commit a1fbbdf

Please sign in to comment.