@@ -541,7 +541,7 @@ document is most commonly accessible through an input called `doc`.
541
541
+
542
542
[source,Painless]
543
543
----
544
- def input = doc['input_datetime'].value;
544
+ ZonedDateTime input = doc['input_datetime'].value;
545
545
String output = input.format(DateTimeFormatter.ISO_INSTANT); <1>
546
546
----
547
547
<1> Note the use of a built-in DateTimeFormatter.
@@ -584,8 +584,8 @@ if (doc.containsKey('start') && doc.containsKey('end')) { <1>
584
584
585
585
if (doc['start'].size() > 0 && doc['end'].size() > 0) { <2>
586
586
587
- def start = doc['start'].value;
588
- def end = doc['end'].value;
587
+ ZonedDateTime start = doc['start'].value;
588
+ ZonedDateTime end = doc['end'].value;
589
589
long differenceInMillis = ChronoUnit.MILLIS.between(start, end);
590
590
591
591
// handle difference in times
@@ -660,7 +660,7 @@ preferred as there is no need to parse it for comparision.
660
660
[source,Painless]
661
661
----
662
662
long now = params['now'];
663
- def inputDateTime = doc['input_datetime'];
663
+ ZonedDateTime inputDateTime = doc['input_datetime'];
664
664
long millisDateTime = zdt.toInstant().toEpochMilli();
665
665
long elapsedTime = now - millisDateTime;
666
666
----
@@ -712,9 +712,194 @@ long elapsedTime = now - millisDateTime;
712
712
String nowString = params['now'];
713
713
ZonedDateTime nowZdt = ZonedDateTime.parse(datetime); <1>
714
714
long now = ZonedDateTime.toInstant().toEpochMilli();
715
- def inputDateTime = doc['input_datetime'];
715
+ ZonedDateTime inputDateTime = doc['input_datetime'];
716
716
long millisDateTime = zdt.toInstant().toEpochMilli();
717
717
long elapsedTime = now - millisDateTime;
718
718
----
719
719
<1> Note this parses the same string datetime every time the script runs. Use a
720
720
numeric datetime to avoid a significant performance hit.
721
+
722
+ ==== Datetime Examples in Contexts
723
+
724
+ ===== Load the Example Data
725
+
726
+ Run the following curl commands to load the data necessary for the context
727
+ examples into an Elasticsearch cluster:
728
+
729
+ . Create {ref}/mapping.html[mappings] for the sample data.
730
+ +
731
+ [source,js]
732
+ ----
733
+ PUT /messages
734
+ {
735
+ "mappings": {
736
+ "properties": {
737
+ "priority": {
738
+ "type": "integer"
739
+ },
740
+ "datetime": {
741
+ "type": "date"
742
+ },
743
+ "message": {
744
+ "type": "text"
745
+ }
746
+ }
747
+ }
748
+ }
749
+ ----
750
+ +
751
+ // CONSOLE
752
+ +
753
+ . Load the sample data.
754
+ +
755
+ [source,js]
756
+ ----
757
+ POST /_bulk
758
+ { "index" : { "_index" : "messages", "_id" : "1" } }
759
+ { "priority": 1, "datetime": "2019-07-17T12:13:14Z", "message": "m1" }
760
+ { "index" : { "_index" : "messages", "_id" : "2" } }
761
+ { "priority": 1, "datetime": "2019-07-24T01:14:59Z", "message": "m2" }
762
+ { "index" : { "_index" : "messages", "_id" : "3" } }
763
+ { "priority": 2, "datetime": "1983-10-14T00:36:42Z", "message": "m3" }
764
+ { "index" : { "_index" : "messages", "_id" : "4" } }
765
+ { "priority": 3, "datetime": "1983-10-10T02:15:15Z", "message": "m4" }
766
+ { "index" : { "_index" : "messages", "_id" : "5" } }
767
+ { "priority": 3, "datetime": "1983-10-10T17:18:19Z", "message": "m5" }
768
+ { "index" : { "_index" : "messages", "_id" : "6" } }
769
+ { "priority": 1, "datetime": "2019-08-03T17:19:31Z", "message": "m6" }
770
+ { "index" : { "_index" : "messages", "_id" : "7" } }
771
+ { "priority": 3, "datetime": "2019-08-04T17:20:00Z", "message": "m7" }
772
+ { "index" : { "_index" : "messages", "_id" : "8" } }
773
+ { "priority": 2, "datetime": "2019-08-04T18:01:01Z", "message": "m8" }
774
+ { "index" : { "_index" : "messages", "_id" : "9" } }
775
+ { "priority": 3, "datetime": "1983-10-10T19:00:45Z", "message": "m9" }
776
+ { "index" : { "_index" : "messages", "_id" : "10" } }
777
+ { "priority": 2, "datetime": "2019-07-23T23:39:54Z", "message": "m10" }
778
+ ----
779
+ +
780
+ // CONSOLE
781
+ // TEST[continued]
782
+
783
+ ===== Day-of-the-Week Bucket Aggregation Example
784
+
785
+ The following example uses a
786
+ {ref}/search-aggregations-bucket-terms-aggregation.html#search-aggregations-bucket-terms-aggregation-script[terms aggregation]
787
+ as part of the
788
+ <<painless-bucket-script-agg-context, bucket script aggregation context>> to
789
+ display the number of messages from each day-of-the-week.
790
+
791
+ [source,js]
792
+ ----
793
+ GET /messages/_search?pretty=true
794
+ {
795
+ "aggs": {
796
+ "day-of-week-count": {
797
+ "terms": {
798
+ "script": "return doc[\"datetime\"].value.getDayOfWeekEnum();"
799
+ }
800
+ }
801
+ }
802
+ }
803
+ ----
804
+ // CONSOLE
805
+ // TEST[continued]
806
+
807
+ ===== Morning/Evening Bucket Aggregation Example
808
+
809
+ The following example uses a
810
+ {ref}/search-aggregations-bucket-terms-aggregation.html#search-aggregations-bucket-terms-aggregation-script[terms aggregation]
811
+ as part of the
812
+ <<painless-bucket-script-agg-context, bucket script aggregation context>> to
813
+ display the number of messages received in the morning versus the evening.
814
+
815
+ [source,js]
816
+ ----
817
+ GET /messages/_search?pretty=true
818
+ {
819
+ "aggs": {
820
+ "am-pm-count": {
821
+ "terms": {
822
+ "script": "return doc[\"datetime\"].value.getHour() < 12 ? \"AM\" : \"PM\";"
823
+ }
824
+ }
825
+ }
826
+ }
827
+ ----
828
+ // CONSOLE
829
+ // TEST[continued]
830
+
831
+ ===== Age of a Message Script Field Example
832
+
833
+ The following example uses a
834
+ {ref}/search-request-script-fields.html[script field] as part of the
835
+ <<painless-field-context, field context>> to display the elapsed time between
836
+ "now" and when a message was received.
837
+
838
+ [source,js]
839
+ ----
840
+ GET /_search?pretty=true
841
+ {
842
+ "query" : {
843
+ "match_all": {}
844
+ },
845
+ "script_fields" : {
846
+ "message_age" : {
847
+ "script" : {
848
+ "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;",
849
+ "params": {
850
+ "now": 1574005645830
851
+ }
852
+ }
853
+ }
854
+ }
855
+ }
856
+ ----
857
+ // CONSOLE
858
+ // TEST[continued]
859
+
860
+ The following shows the script broken into multiple lines:
861
+
862
+ [source,Painless]
863
+ ----
864
+ ZonedDateTime now = ZonedDateTime.ofInstant(
865
+ Instant.ofEpochMilli(params['now']), ZoneId.of('Z')); <1>
866
+ ZonedDateTime mdt = doc['datetime'].value; <2>
867
+
868
+ String age;
869
+
870
+ long years = mdt.until(now, ChronoUnit.YEARS); <3>
871
+ age = years + 'Y '; <4>
872
+ mdt = mdt.plusYears(years); <5>
873
+
874
+ long months = mdt.until(now, ChronoUnit.MONTHS);
875
+ age += months + 'M ';
876
+ mdt = mdt.plusMonths(months);
877
+
878
+ long days = mdt.until(now, ChronoUnit.DAYS);
879
+ age += days + 'D ';
880
+ mdt = mdt.plusDays(days);
881
+
882
+ long hours = mdt.until(now, ChronoUnit.HOURS);
883
+ age += hours + 'h ';
884
+ mdt = mdt.plusHours(hours);
885
+
886
+ long minutes = mdt.until(now, ChronoUnit.MINUTES);
887
+ age += minutes + 'm ';
888
+ mdt = mdt.plusMinutes(minutes);
889
+
890
+ long seconds = mdt.until(now, ChronoUnit.SECONDS);
891
+ age += hours + 's';
892
+
893
+ return age; <6>
894
+ ----
895
+ <1> Parse the datetime "now" as input from the user-defined params.
896
+ <2> Store the datetime the message was received as a `ZonedDateTime`.
897
+ <3> Find the difference in years between "now" and the datetime the message was
898
+ received.
899
+ <4> Add the difference in years later returned in the format
900
+ `Y <years> ...` for the age of a message.
901
+ <5> Add the years so only the remainder of the months, days, etc. remain as the
902
+ difference between "now" and the datetime the message was received. Repeat this
903
+ pattern until the desired granularity is reached (seconds in this example).
904
+ <6> Return the age of the message in the format
905
+ `Y <years> M <months> D <days> h <hours> m <minutes> s <seconds>`.
0 commit comments