Datetime examples in contexts
Elastic Cloud Serverless projects are autoscaled environments, fully managed by Elastic and available on Elastic Cloud. Availability This functionality is generally available and ready for production usage. Serverless interfaces and procedures might differ from classic Elastic Stack deployments. The Elastic Stack includes Elastic's core products such as Elasticsearch, Kibana, Logstash, and Beats. Availability This functionality is generally available and ready for production usage. Unless stated otherwise on the page, this functionality is available when your Elastic Stack is deployed on Elastic Cloud Hosted, Elastic Cloud Enterprise, Elastic Cloud on Kubernetes, and self-managed environments. This documentation corresponds to the latest patch available for each minor version. If you're not using the latest patch, check the release notes for changes.
Serverless
Generally available
Stack
Generally available
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.
JSON PUT /messages{ "mappings": { "properties": { "priority": { "type": "integer" }, "datetime": { "type": "date" }, "message": { "type": "text" } } } }Load the sample data.
JSON 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>.