OpenSearch/docs/painless/painless-contexts/painless-ingest-processor-c...

144 lines
5.7 KiB
Plaintext

[[painless-ingest-processor-context]]
=== Ingest processor context
Use a Painless script in an {ref}/script-processor.html[ingest processor]
to modify documents upon insertion.
*Variables*
`params` (`Map`, read-only)::
User-defined parameters passed in as part of the query.
{ref}/mapping-index-field.html[`ctx['_index']`] (`String`)::
The name of the index.
{ref}/mapping-type-field.html[`ctx['_type']`] (`String`)::
The type of document within an index.
`ctx` (`Map`)::
Contains extracted JSON in a `Map` and `List` structure for the fields
that are part of the document.
*Side Effects*
{ref}/mapping-index-field.html[`ctx['_index']`]::
Modify this to change the destination index for the current document.
{ref}/mapping-type-field.html[`ctx['_type']`]::
Modify this to change the type for the current document.
`ctx` (`Map`)::
Modify the values in the `Map/List` structure to add, modify, or delete
the fields of a document.
*Return*
void::
No expected return value.
*API*
The standard <<painless-api-reference, Painless API>> is available.
*Example*
To run this example, first follow the steps in
<<painless-context-examples, context examples>>.
The seat data contains:
* A date in the format `YYYY-MM-DD` where the second digit of both month and day
is optional.
* A time in the format HH:MM* where the second digit of both hours and minutes
is optional. The star (*) represents either the `String` `AM` or `PM`.
The following ingest script processes the date and time `Strings` and stores the
result in a `datetime` field.
[source,Painless]
----
String[] dateSplit = ctx.date.splitOnToken("-"); <1>
String year = dateSplit[0].trim();
String month = dateSplit[1].trim();
if (month.length() == 1) { <2>
month = "0" + month;
}
String day = dateSplit[2].trim();
if (day.length() == 1) { <3>
day = "0" + day;
}
boolean pm = ctx.time.substring(ctx.time.length() - 2).equals("PM"); <4>
String[] timeSplit = ctx.time.substring(0,
ctx.time.length() - 2).splitOnToken(":"); <5>
int hours = Integer.parseInt(timeSplit[0].trim());
int minutes = Integer.parseInt(timeSplit[1].trim());
if (pm) { <6>
hours += 12;
}
String dts = year + "-" + month + "-" + day + "T" +
(hours < 10 ? "0" + hours : "" + hours) + ":" +
(minutes < 10 ? "0" + minutes : "" + minutes) +
":00+08:00"; <7>
ZonedDateTime dt = ZonedDateTime.parse(
dts, DateTimeFormatter.ISO_OFFSET_DATE_TIME); <8>
ctx.datetime = dt.getLong(ChronoField.INSTANT_SECONDS)*1000L; <9>
----
<1> Uses the `splitOnToken` function to separate the date `String` from the
seat data into year, month, and day `Strings`.
Note::
* The use of the `ctx` ingest processor context variable to retrieve the
data from the `date` field.
<2> Appends the <<string-literals, string literal>> `"0"` value to a single
digit month since the format of the seat data allows for this case.
<3> Appends the <<string-literals, string literal>> `"0"` value to a single
digit day since the format of the seat data allows for this case.
<4> Sets the <<primitive-types, `boolean type`>>
<<painless-variables, variable>> to `true` if the time `String` is a time
in the afternoon or evening.
Note::
* The use of the `ctx` ingest processor context variable to retrieve the
data from the `time` field.
<5> Uses the `splitOnToken` function to separate the time `String` from the
seat data into hours and minutes `Strings`.
Note::
* The use of the `substring` method to remove the `AM` or `PM` portion of
the time `String`.
* The use of the `ctx` ingest processor context variable to retrieve the
data from the `date` field.
<6> If the time `String` is an afternoon or evening value adds the
<<integer-literals, integer literal>> `12` to the existing hours to move to
a 24-hour based time.
<7> Builds a new time `String` that is parsable using existing API methods.
<8> Creates a `ZonedDateTime` <<reference-types, reference type>> value by using
the API method `parse` to parse the new time `String`.
<9> Sets the datetime field `datetime` to the number of milliseconds retrieved
from the API method `getLong`.
Note::
* The use of the `ctx` ingest processor context variable to set the field
`datetime`. Manipulate each document's fields with the `ctx` variable as
each document is indexed.
Submit the following request:
[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;"
}
}
]
}
----