Datetime examples in contexts
Serverless Stack
Try out these Painless datetime examples that include real world contexts.
Run the following curl commands to load the data necessary for the context examples into an Elasticsearch cluster:
Create mappings for the sample data.
PUT /messages{ "mappings": { "properties": { "priority": { "type": "integer" }, "datetime": { "type": "date" }, "message": { "type": "text" } } } }Load the sample data.
POST /_bulk{ "index" : { "_index" : "messages", "_id" : "1" } } { "priority": 1, "datetime": "2019-07-17T12:13:14Z", "message": "m1" } { "index" : { "_index" : "messages", "_id" : "2" } } { "priority": 1, "datetime": "2019-07-24T01:14:59Z", "message": "m2" } { "index" : { "_index" : "messages", "_id" : "3" } } { "priority": 2, "datetime": "1983-10-14T00:36:42Z", "message": "m3" } { "index" : { "_index" : "messages", "_id" : "4" } } { "priority": 3, "datetime": "1983-10-10T02:15:15Z", "message": "m4" } { "index" : { "_index" : "messages", "_id" : "5" } } { "priority": 3, "datetime": "1983-10-10T17:18:19Z", "message": "m5" } { "index" : { "_index" : "messages", "_id" : "6" } } { "priority": 1, "datetime": "2019-08-03T17:19:31Z", "message": "m6" } { "index" : { "_index" : "messages", "_id" : "7" } } { "priority": 3, "datetime": "2019-08-04T17:20:00Z", "message": "m7" } { "index" : { "_index" : "messages", "_id" : "8" } } { "priority": 2, "datetime": "2019-08-04T18:01:01Z", "message": "m8" } { "index" : { "_index" : "messages", "_id" : "9" } } { "priority": 3, "datetime": "1983-10-10T19:00:45Z", "message": "m9" } { "index" : { "_index" : "messages", "_id" : "10" } } { "priority": 2, "datetime": "2019-07-23T23:39:54Z", "message": "m10" }
The following example uses a terms aggregation as part of the bucket script aggregation context to display the number of messages from each day-of-the-week.
GET /messages/_search?pretty=true
{
"aggs": {
"day-of-week-count": {
"terms": {
"script": "return doc[\"datetime\"].value.getDayOfWeekEnum();"
}
}
}
}
The following example uses a terms aggregation as part of the bucket script aggregation context to display the number of messages received in the morning versus the evening.
GET /messages/_search?pretty=true
{
"aggs": {
"am-pm-count": {
"terms": {
"script": "return doc[\"datetime\"].value.getHour() < 12 ? \"AM\" : \"PM\";"
}
}
}
}
The following example uses a script field as part of the field context to display the elapsed time between "now" and when a message was received.
GET /_search?pretty=true
{
"query": {
"match_all": {}
},
"script_fields": {
"message_age": {
"script": {
"source": "ZonedDateTime now = ZonedDateTime.ofInstant(Instant.ofEpochMilli(params[\"now\"]), ZoneId.of(\"Z\")); ZonedDateTime mdt = doc[\"datetime\"].value; String age; long years = mdt.until(now, ChronoUnit.YEARS); age = years + \"Y \"; mdt = mdt.plusYears(years); long months = mdt.until(now, ChronoUnit.MONTHS); age += months + \"M \"; mdt = mdt.plusMonths(months); long days = mdt.until(now, ChronoUnit.DAYS); age += days + \"D \"; mdt = mdt.plusDays(days); long hours = mdt.until(now, ChronoUnit.HOURS); age += hours + \"h \"; mdt = mdt.plusHours(hours); long minutes = mdt.until(now, ChronoUnit.MINUTES); age += minutes + \"m \"; mdt = mdt.plusMinutes(minutes); long seconds = mdt.until(now, ChronoUnit.SECONDS); age += hours + \"s\"; return age;",
"params": {
"now": 1574005645830
}
}
}
}
}
The following shows the script broken into multiple lines:
ZonedDateTime now = ZonedDateTime.ofInstant(
Instant.ofEpochMilli(params['now']), ZoneId.of('Z'));
ZonedDateTime mdt = doc['datetime'].value;
String age;
long years = mdt.until(now, ChronoUnit.YEARS);
age = years + 'Y ';
mdt = mdt.plusYears(years);
long months = mdt.until(now, ChronoUnit.MONTHS);
age += months + 'M ';
mdt = mdt.plusMonths(months);
long days = mdt.until(now, ChronoUnit.DAYS);
age += days + 'D ';
mdt = mdt.plusDays(days);
long hours = mdt.until(now, ChronoUnit.HOURS);
age += hours + 'h ';
mdt = mdt.plusHours(hours);
long minutes = mdt.until(now, ChronoUnit.MINUTES);
age += minutes + 'm ';
mdt = mdt.plusMinutes(minutes);
long seconds = mdt.until(now, ChronoUnit.SECONDS);
age += hours + 's';
return age;
- Parse the datetime "now" as input from the user-defined params.
- Store the datetime the message was received as a
ZonedDateTime. - Find the difference in years between "now" and the datetime the message was received.
- Add the difference in years later returned in the format
Y <years> ...for the age of a message. - Add the years so only the remainder of the months, days, etc. remain as the difference between "now" and the datetime the message was received. Repeat this pattern until the desired granularity is reached (seconds in this example).
- Return the age of the message in the format
Y <years> M <months> D <days> h <hours> m <minutes> s <seconds>.