@@ -27,7 +27,7 @@ to modify documents upon insertion.
27
27
{ref}/mapping-type-field.html[`ctx['_type']`]::
28
28
Modify this to change the type for the current document.
29
29
30
- `ctx` (`Map`, read-only )::
30
+ `ctx` (`Map`)::
31
31
Modify the values in the `Map/List` structure to add, modify, or delete
32
32
the fields of a document.
33
33
@@ -38,4 +38,158 @@ void::
38
38
39
39
*API*
40
40
41
- The standard <<painless-api-reference, Painless API>> is available.
41
+ The standard <<painless-api-reference, Painless API>> is available.
42
+
43
+ *Example*
44
+
45
+ To run this example, first follow the steps in
46
+ <<painless-context-examples, context examples>>.
47
+
48
+ The seat data contains:
49
+
50
+ * A date in the format `YYYY-MM-DD` where the second digit of both month and day
51
+ is optional.
52
+ * A time in the format HH:MM* where the second digit of both hours and minutes
53
+ is optional. The star (*) represents either the `String` `AM` or `PM`.
54
+
55
+ The following ingest script processes the date and time `Strings` and stores the
56
+ result in a `datetime` field.
57
+
58
+ [source,Painless]
59
+ ----
60
+ String[] split(String s, char d) { <1>
61
+ int count = 0;
62
+
63
+ for (char c : s.toCharArray()) { <2>
64
+ if (c == d) {
65
+ ++count;
66
+ }
67
+ }
68
+
69
+ if (count == 0) {
70
+ return new String[] {s}; <3>
71
+ }
72
+
73
+ String[] r = new String[count + 1]; <4>
74
+ int i0 = 0, i1 = 0;
75
+ count = 0;
76
+
77
+ for (char c : s.toCharArray()) { <5>
78
+ if (c == d) {
79
+ r[count++] = s.substring(i0, i1);
80
+ i0 = i1 + 1;
81
+ }
82
+
83
+ ++i1;
84
+ }
85
+
86
+ r[count] = s.substring(i0, i1); <6>
87
+
88
+ return r;
89
+ }
90
+
91
+ String[] dateSplit = split(ctx.date, (char)"-"); <7>
92
+ String year = dateSplit[0].trim();
93
+ String month = dateSplit[1].trim();
94
+
95
+ if (month.length() == 1) { <8>
96
+ month = "0" + month;
97
+ }
98
+
99
+ String day = dateSplit[2].trim();
100
+
101
+ if (day.length() == 1) { <9>
102
+ day = "0" + day;
103
+ }
104
+
105
+ boolean pm = ctx.time.substring(ctx.time.length() - 2).equals("PM"); <10>
106
+ String[] timeSplit = split(
107
+ ctx.time.substring(0, ctx.time.length() - 2), (char)":"); <11>
108
+ int hours = Integer.parseInt(timeSplit[0].trim());
109
+ int minutes = Integer.parseInt(timeSplit[1].trim());
110
+
111
+ if (pm) { <12>
112
+ hours += 12;
113
+ }
114
+
115
+ String dts = year + "-" + month + "-" + day + "T" +
116
+ (hours < 10 ? "0" + hours : "" + hours) + ":" +
117
+ (minutes < 10 ? "0" + minutes : "" + minutes) +
118
+ ":00+08:00"; <13>
119
+
120
+ ZonedDateTime dt = ZonedDateTime.parse(
121
+ dts, DateTimeFormatter.ISO_OFFSET_DATE_TIME); <14>
122
+ ctx.datetime = dt.getLong(ChronoField.INSTANT_SECONDS)*1000L; <15>
123
+ ----
124
+ <1> Creates a `split` <<painless-functions, function>> to split a
125
+ <<string-type, `String`>> type value using a <<primitive-types, `char`>>
126
+ type value as the delimiter. This is useful for handling the necessity of
127
+ pulling out the individual pieces of the date and time `Strings` from the
128
+ original seat data.
129
+ <2> The first pass through each `char` in the `String` collects how many new
130
+ `Strings` the original is split into.
131
+ <3> Returns the original `String` if there are no instances of the delimiting
132
+ `char`.
133
+ <4> Creates an <<array-type, array type>> value to collect the split `Strings`
134
+ into based on the number of `char` delimiters found in the first pass.
135
+ <5> The second pass through each `char` in the `String` collects each split
136
+ substring into an array type value of `Strings`.
137
+ <6> Collects the last substring into the array type value of `Strings`.
138
+ <7> Uses the `split` function to separate the date `String` from the seat data
139
+ into year, month, and day `Strings`.
140
+ Note::
141
+ * The use of a `String` type value to `char` type value
142
+ <<string-character-casting, cast>> as part of the second argument since
143
+ character literals do not exist.
144
+ * The use of the `ctx` ingest processor context variable to retrieve the
145
+ data from the `date` field.
146
+ <8> Appends the <<string-literals, string literal>> `"0"` value to a single
147
+ digit month since the format of the seat data allows for this case.
148
+ <9> Appends the <<string-literals, string literal>> `"0"` value to a single
149
+ digit day since the format of the seat data allows for this case.
150
+ <10> Sets the <<primitive-types, `boolean type`>>
151
+ <<painless-variables, variable>> to `true` if the time `String` is a time
152
+ in the afternoon or evening.
153
+ Note::
154
+ * The use of the `ctx` ingest processor context variable to retrieve the
155
+ data from the `time` field.
156
+ <11> Uses the `split` function to separate the time `String` from the seat data
157
+ into hours and minutes `Strings`.
158
+ Note::
159
+ * The use of the `substring` method to remove the `AM` or `PM` portion of
160
+ the time `String`.
161
+ * The use of a `String` type value to `char` type value
162
+ <<string-character-casting, cast>> as part of the second argument since
163
+ character literals do not exist.
164
+ * The use of the `ctx` ingest processor context variable to retrieve the
165
+ data from the `date` field.
166
+ <12> If the time `String` is an afternoon or evening value adds the
167
+ <<integer-literals, integer literal>> `12` to the existing hours to move to
168
+ a 24-hour based time.
169
+ <13> Builds a new time `String` that is parsable using existing API methods.
170
+ <14> Creates a `ZonedDateTime` <<reference-types, reference type>> value by using
171
+ the API method `parse` to parse the new time `String`.
172
+ <15> Sets the datetime field `datetime` to the number of milliseconds retrieved
173
+ from the API method `getLong`.
174
+ Note::
175
+ * The use of the `ctx` ingest processor context variable to set the field
176
+ `datetime`. Manipulate each document's fields with the `ctx` variable as
177
+ each document is indexed.
178
+
179
+ Submit the following request:
180
+
181
+ [source,js]
182
+ ----
183
+ PUT /_ingest/pipeline/seats
184
+ {
185
+ "description": "update datetime for seats",
186
+ "processors": [
187
+ {
188
+ "script": {
189
+ "source": "String[] split(String s, char d) { int count = 0; for (char c : s.toCharArray()) { if (c == d) { ++count; } } if (count == 0) { return new String[] {s}; } String[] r = new String[count + 1]; int i0 = 0, i1 = 0; count = 0; for (char c : s.toCharArray()) { if (c == d) { r[count++] = s.substring(i0, i1); i0 = i1 + 1; } ++i1; } r[count] = s.substring(i0, i1); return r; } String[] dateSplit = split(ctx.date, (char)\"-\"); 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 = split(ctx.time.substring(0, ctx.time.length() - 2), (char)\":\"); 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;"
190
+ }
191
+ }
192
+ ]
193
+ }
194
+ ----
195
+ // CONSOLE
0 commit comments