3131import org .apache .lucene .store .Directory ;
3232import org .apache .lucene .util .BytesRef ;
3333import org .elasticsearch .ElasticsearchParseException ;
34+ import org .elasticsearch .common .CheckedBiConsumer ;
3435import org .elasticsearch .common .CheckedConsumer ;
3536import org .elasticsearch .index .mapper .DateFieldMapper ;
3637import org .elasticsearch .index .mapper .KeywordFieldMapper ;
4243import org .elasticsearch .search .aggregations .support .AggregationInspectionHelper ;
4344
4445import java .io .IOException ;
46+ import java .time .Instant ;
4547import java .time .ZoneOffset ;
4648import java .time .ZonedDateTime ;
4749import java .util .Collections ;
5254
5355public class DateRangeAggregatorTests extends AggregatorTestCase {
5456
55- private String NUMBER_FIELD_NAME = "number" ;
56- private String UNMAPPED_FIELD_NAME = "field_not_appearing_in_this_index" ;
57- private String DATE_FIELD_NAME = "date" ;
57+ private static final String NUMBER_FIELD_NAME = "number" ;
58+ private static final String DATE_FIELD_NAME = "date" ;
5859
59- private long milli1 = ZonedDateTime .of (2015 , 11 , 13 , 16 , 14 , 34 , 0 , ZoneOffset .UTC ).toInstant (). toEpochMilli ();
60- private long milli2 = ZonedDateTime .of (2016 , 11 , 13 , 16 , 14 , 34 , 0 , ZoneOffset .UTC ).toInstant (). toEpochMilli ();
60+ private Instant t1 = ZonedDateTime .of (2015 , 11 , 13 , 16 , 14 , 34 , 0 , ZoneOffset .UTC ).toInstant ();
61+ private Instant t2 = ZonedDateTime .of (2016 , 11 , 13 , 16 , 14 , 34 , 0 , ZoneOffset .UTC ).toInstant ();
6162
6263 public void testNoMatchingField () throws IOException {
63- testBothResolutions (new MatchAllDocsQuery (), iw -> {
64- iw .addDocument (singleton (new SortedNumericDocValuesField ("bogus_field_name" , 7 )));
65- iw .addDocument (singleton (new SortedNumericDocValuesField ("bogus_field_name" , 2 )));
66- iw .addDocument (singleton (new SortedNumericDocValuesField ("bogus_field_name" , 3 )));
64+ testBothResolutions (new MatchAllDocsQuery (), ( iw , resolution ) -> {
65+ iw .addDocument (singleton (new SortedNumericDocValuesField ("bogus_field_name" , resolution . convert ( Instant . ofEpochMilli ( 7 )) )));
66+ iw .addDocument (singleton (new SortedNumericDocValuesField ("bogus_field_name" , resolution . convert ( Instant . ofEpochMilli ( 2 )) )));
67+ iw .addDocument (singleton (new SortedNumericDocValuesField ("bogus_field_name" , resolution . convert ( Instant . ofEpochMilli ( 3 )) )));
6768 }, range -> {
6869 List <? extends InternalRange .Bucket > ranges = range .getBuckets ();
6970 assertEquals (2 , ranges .size ());
@@ -73,11 +74,10 @@ public void testNoMatchingField() throws IOException {
7374 });
7475 }
7576
76- @ AwaitsFix (bugUrl ="https://github.com/elastic/elasticsearch/issues/57651" )
7777 public void testMatchesSortedNumericDocValues () throws IOException {
78- testBothResolutions (new MatchAllDocsQuery (), iw -> {
79- iw .addDocument (singleton (new SortedNumericDocValuesField (DATE_FIELD_NAME , milli1 )));
80- iw .addDocument (singleton (new SortedNumericDocValuesField (DATE_FIELD_NAME , milli2 )));
78+ testBothResolutions (new MatchAllDocsQuery (), ( iw , resolution ) -> {
79+ iw .addDocument (singleton (new SortedNumericDocValuesField (DATE_FIELD_NAME , resolution . convert ( t1 ) )));
80+ iw .addDocument (singleton (new SortedNumericDocValuesField (DATE_FIELD_NAME , resolution . convert ( t2 ) )));
8181 }, range -> {
8282 List <? extends InternalRange .Bucket > ranges = range .getBuckets ();
8383 assertEquals (2 , ranges .size ());
@@ -87,11 +87,10 @@ public void testMatchesSortedNumericDocValues() throws IOException {
8787 });
8888 }
8989
90- @ AwaitsFix (bugUrl ="https://github.com/elastic/elasticsearch/issues/57651" )
9190 public void testMatchesNumericDocValues () throws IOException {
92- testBothResolutions (new MatchAllDocsQuery (), iw -> {
93- iw .addDocument (singleton (new NumericDocValuesField (DATE_FIELD_NAME , milli1 )));
94- iw .addDocument (singleton (new NumericDocValuesField (DATE_FIELD_NAME , milli2 )));
91+ testBothResolutions (new MatchAllDocsQuery (), ( iw , resolution ) -> {
92+ iw .addDocument (singleton (new NumericDocValuesField (DATE_FIELD_NAME , resolution . convert ( t1 ) )));
93+ iw .addDocument (singleton (new NumericDocValuesField (DATE_FIELD_NAME , resolution . convert ( t2 ) )));
9594 }, range -> {
9695 List <? extends InternalRange .Bucket > ranges = range .getBuckets ();
9796 assertEquals (2 , ranges .size ());
@@ -101,26 +100,26 @@ public void testMatchesNumericDocValues() throws IOException {
101100 });
102101 }
103102
104- public void testMissingDateStringWithDateField () throws IOException {
105- DateFieldMapper .DateFieldType fieldType = new DateFieldMapper .DateFieldType (DATE_FIELD_NAME );
103+ public void testMissingDateStringWithDateField () throws IOException {
104+ DateFieldMapper .DateFieldType fieldType = new DateFieldMapper .DateFieldType (DATE_FIELD_NAME );
106105
107- DateRangeAggregationBuilder aggregationBuilder = new DateRangeAggregationBuilder ("date_range" )
108- .field (DATE_FIELD_NAME )
109- .missing ("2015-11-13T16:14:34" )
110- .addRange ("2015-11-13" , "2015-11-14" );
106+ DateRangeAggregationBuilder aggregationBuilder = new DateRangeAggregationBuilder ("date_range" )
107+ .field (DATE_FIELD_NAME )
108+ .missing ("2015-11-13T16:14:34" )
109+ .addRange ("2015-11-13" , "2015-11-14" );
111110
112- testCase (aggregationBuilder , new MatchAllDocsQuery (), iw -> {
113- iw .addDocument (singleton (new SortedNumericDocValuesField (DATE_FIELD_NAME , milli1 )));
114- iw .addDocument (singleton (new SortedNumericDocValuesField (DATE_FIELD_NAME , milli2 )));
115- // Missing will apply to this document
116- iw .addDocument (singleton (new SortedNumericDocValuesField (NUMBER_FIELD_NAME , 7 )));
117- }, range -> {
118- List <? extends InternalRange .Bucket > ranges = range .getBuckets ();
119- assertEquals (1 , ranges .size ());
120- assertEquals (2 , ranges .get (0 ).getDocCount ());
121- assertTrue (AggregationInspectionHelper .hasValue (range ));
122- }, fieldType );
123- }
111+ testCase (aggregationBuilder , new MatchAllDocsQuery (), iw -> {
112+ iw .addDocument (singleton (new SortedNumericDocValuesField (DATE_FIELD_NAME , t1 . toEpochMilli () )));
113+ iw .addDocument (singleton (new SortedNumericDocValuesField (DATE_FIELD_NAME , t2 . toEpochMilli () )));
114+ // Missing will apply to this document
115+ iw .addDocument (singleton (new SortedNumericDocValuesField (NUMBER_FIELD_NAME , 7 )));
116+ }, range -> {
117+ List <? extends InternalRange .Bucket > ranges = range .getBuckets ();
118+ assertEquals (1 , ranges .size ());
119+ assertEquals (2 , ranges .get (0 ).getDocCount ());
120+ assertTrue (AggregationInspectionHelper .hasValue (range ));
121+ }, fieldType );
122+ }
124123
125124 public void testNumberFieldDateRanges () throws IOException {
126125 DateRangeAggregationBuilder aggregationBuilder = new DateRangeAggregationBuilder ("date_range" )
@@ -157,29 +156,49 @@ public void testNumberFieldNumberRanges() throws IOException {
157156 }
158157
159158 public void testMissingDateStringWithNumberField () throws IOException {
160- DateRangeAggregationBuilder aggregationBuilder = new DateRangeAggregationBuilder ("date_range" )
161- .field (NUMBER_FIELD_NAME )
162- .addRange ("2015-11-13" , "2015-11-14" )
163- .missing ("1979-01-01T00:00:00" );
164-
165- MappedFieldType fieldType
166- = new NumberFieldMapper .NumberFieldType (NUMBER_FIELD_NAME , NumberFieldMapper .NumberType .INTEGER );
167-
168- expectThrows (NumberFormatException .class ,
169- () -> testCase (aggregationBuilder , new MatchAllDocsQuery (), iw -> {
170- iw .addDocument (singleton (new NumericDocValuesField (NUMBER_FIELD_NAME , 7 )));
171- iw .addDocument (singleton (new NumericDocValuesField (NUMBER_FIELD_NAME , 1 )));
172- }, range -> fail ("Should have thrown exception" ), fieldType ));
173- }
159+ DateRangeAggregationBuilder aggregationBuilder = new DateRangeAggregationBuilder ("date_range" )
160+ .field (NUMBER_FIELD_NAME )
161+ .addRange ("2015-11-13" , "2015-11-14" )
162+ .missing ("1979-01-01T00:00:00" );
163+
164+ MappedFieldType fieldType
165+ = new NumberFieldMapper .NumberFieldType (NUMBER_FIELD_NAME , NumberFieldMapper .NumberType .INTEGER );
166+
167+ expectThrows (NumberFormatException .class ,
168+ () -> testCase (aggregationBuilder , new MatchAllDocsQuery (), iw -> {
169+ iw .addDocument (singleton (new NumericDocValuesField (NUMBER_FIELD_NAME , 7 )));
170+ iw .addDocument (singleton (new NumericDocValuesField (NUMBER_FIELD_NAME , 1 )));
171+ }, range -> fail ("Should have thrown exception" ), fieldType ));
172+ }
173+
174+ public void testUnmappedWithMissingNumber () throws IOException {
175+ DateRangeAggregationBuilder aggregationBuilder = new DateRangeAggregationBuilder ("date_range" )
176+ .field ("does_not_exist" )
177+ .addRange ("2015-11-13" , "2015-11-14" )
178+ .missing (1447438575000L ); // 2015-11-13 6:16:15
179+
180+ MappedFieldType fieldType
181+ = new NumberFieldMapper .NumberFieldType (NUMBER_FIELD_NAME , NumberFieldMapper .NumberType .INTEGER );
182+
183+ testCase (aggregationBuilder , new MatchAllDocsQuery (), iw -> {
184+ iw .addDocument (singleton (new NumericDocValuesField (NUMBER_FIELD_NAME , 7 )));
185+ iw .addDocument (singleton (new NumericDocValuesField (NUMBER_FIELD_NAME , 1 )));
186+ }, range -> {
187+ List <? extends InternalRange .Bucket > ranges = range .getBuckets ();
188+ assertEquals (1 , ranges .size ());
189+ assertEquals (2 , ranges .get (0 ).getDocCount ());
190+ assertTrue (AggregationInspectionHelper .hasValue (range ));
191+ }, fieldType );
192+ }
174193
175- public void testUnmappedWithMissingNumber () throws IOException {
176- DateRangeAggregationBuilder aggregationBuilder = new DateRangeAggregationBuilder ("date_range" )
177- .field ("does_not_exist" )
178- .addRange ("2015-11-13" , "2015-11-14" )
179- .missing (1447438575000L ); // 2015-11-13 6:16:15
194+ public void testUnmappedWithMissingDate () throws IOException {
195+ DateRangeAggregationBuilder aggregationBuilder = new DateRangeAggregationBuilder ("date_range" )
196+ .field ("does_not_exist" )
197+ .addRange ("2015-11-13" , "2015-11-14" )
198+ .missing (" 2015-11-13T10:11:12" );
180199
181- MappedFieldType fieldType
182- = new NumberFieldMapper .NumberFieldType (NUMBER_FIELD_NAME , NumberFieldMapper .NumberType .INTEGER );
200+ MappedFieldType fieldType
201+ = new NumberFieldMapper .NumberFieldType (NUMBER_FIELD_NAME , NumberFieldMapper .NumberType .INTEGER );
183202
184203 testCase (aggregationBuilder , new MatchAllDocsQuery (), iw -> {
185204 iw .addDocument (singleton (new NumericDocValuesField (NUMBER_FIELD_NAME , 7 )));
@@ -190,81 +209,72 @@ public void testUnmappedWithMissingNumber() throws IOException {
190209 assertEquals (2 , ranges .get (0 ).getDocCount ());
191210 assertTrue (AggregationInspectionHelper .hasValue (range ));
192211 }, fieldType );
193- }
194-
195- public void testUnmappedWithMissingDate () throws IOException {
196- DateRangeAggregationBuilder aggregationBuilder = new DateRangeAggregationBuilder ("date_range" )
197- .field ("does_not_exist" )
198- .addRange ("2015-11-13" , "2015-11-14" )
199- .missing ("2015-11-13T10:11:12" );
200-
201- MappedFieldType fieldType
202- = new NumberFieldMapper .NumberFieldType (NUMBER_FIELD_NAME , NumberFieldMapper .NumberType .INTEGER );
203-
204- testCase (aggregationBuilder , new MatchAllDocsQuery (), iw -> {
205- iw .addDocument (singleton (new NumericDocValuesField (NUMBER_FIELD_NAME , 7 )));
206- iw .addDocument (singleton (new NumericDocValuesField (NUMBER_FIELD_NAME , 1 )));
207- }, range -> {
208- List <? extends InternalRange .Bucket > ranges = range .getBuckets ();
209- assertEquals (1 , ranges .size ());
210- assertEquals (2 , ranges .get (0 ).getDocCount ());
211- assertTrue (AggregationInspectionHelper .hasValue (range ));
212- }, fieldType );
213- }
212+ }
214213
215- public void testKeywordField () {
216- DateRangeAggregationBuilder aggregationBuilder = new DateRangeAggregationBuilder ("date_range" )
217- .field ("not_a_number" )
218- .addRange ("2015-11-13" , "2015-11-14" );
214+ public void testKeywordField () {
215+ DateRangeAggregationBuilder aggregationBuilder = new DateRangeAggregationBuilder ("date_range" )
216+ .field ("not_a_number" )
217+ .addRange ("2015-11-13" , "2015-11-14" );
219218
220- MappedFieldType fieldType = new KeywordFieldMapper .KeywordFieldType ("not_a_number" );
219+ MappedFieldType fieldType = new KeywordFieldMapper .KeywordFieldType ("not_a_number" );
221220
222- IllegalArgumentException e = expectThrows (IllegalArgumentException .class ,
223- () -> testCase (aggregationBuilder , new MatchAllDocsQuery (), iw -> {
224- iw .addDocument (singleton (new SortedSetDocValuesField ("string" , new BytesRef ("foo" ))));
225- }, range -> fail ("Should have thrown exception" ), fieldType ));
226- assertEquals ("Field [not_a_number] of type [keyword] is not supported for aggregation [date_range]" ,
227- e .getMessage ());
228- }
221+ IllegalArgumentException e = expectThrows (IllegalArgumentException .class ,
222+ () -> testCase (aggregationBuilder , new MatchAllDocsQuery (), iw -> {
223+ iw .addDocument (singleton (new SortedSetDocValuesField ("string" , new BytesRef ("foo" ))));
224+ }, range -> fail ("Should have thrown exception" ), fieldType ));
225+ assertEquals ("Field [not_a_number] of type [keyword] is not supported for aggregation [date_range]" ,
226+ e .getMessage ());
227+ }
229228
230- public void testBadMissingField () {
231- DateRangeAggregationBuilder aggregationBuilder = new DateRangeAggregationBuilder ("date_range" )
232- .field (NUMBER_FIELD_NAME )
233- .addRange ("2020-01-01T00:00:00" , "2020-01-02T00:00:00" )
234- .missing ("bogus" );
229+ public void testBadMissingField () {
230+ DateRangeAggregationBuilder aggregationBuilder = new DateRangeAggregationBuilder ("date_range" )
231+ .field (NUMBER_FIELD_NAME )
232+ .addRange ("2020-01-01T00:00:00" , "2020-01-02T00:00:00" )
233+ .missing ("bogus" );
235234
236- MappedFieldType fieldType
237- = new NumberFieldMapper .NumberFieldType (NUMBER_FIELD_NAME , NumberFieldMapper .NumberType .INTEGER );
235+ MappedFieldType fieldType
236+ = new NumberFieldMapper .NumberFieldType (NUMBER_FIELD_NAME , NumberFieldMapper .NumberType .INTEGER );
238237
239- expectThrows (NumberFormatException .class ,
240- () -> testCase (aggregationBuilder , new MatchAllDocsQuery (), iw -> {
241- iw .addDocument (singleton (new NumericDocValuesField (NUMBER_FIELD_NAME , 7 )));
242- iw .addDocument (singleton (new NumericDocValuesField (NUMBER_FIELD_NAME , 1 )));
243- }, range -> fail ("Should have thrown exception" ), fieldType ));
244- }
238+ expectThrows (NumberFormatException .class ,
239+ () -> testCase (aggregationBuilder , new MatchAllDocsQuery (), iw -> {
240+ iw .addDocument (singleton (new NumericDocValuesField (NUMBER_FIELD_NAME , 7 )));
241+ iw .addDocument (singleton (new NumericDocValuesField (NUMBER_FIELD_NAME , 1 )));
242+ }, range -> fail ("Should have thrown exception" ), fieldType ));
243+ }
245244
246- public void testUnmappedWithBadMissingField () {
247- DateRangeAggregationBuilder aggregationBuilder = new DateRangeAggregationBuilder ("date_range" )
248- .field ("does_not_exist" )
249- .addRange ("2020-01-01T00:00:00" , "2020-01-02T00:00:00" )
250- .missing ("bogus" );
245+ public void testUnmappedWithBadMissingField () {
246+ DateRangeAggregationBuilder aggregationBuilder = new DateRangeAggregationBuilder ("date_range" )
247+ .field ("does_not_exist" )
248+ .addRange ("2020-01-01T00:00:00" , "2020-01-02T00:00:00" )
249+ .missing ("bogus" );
251250
252- MappedFieldType fieldType
253- = new NumberFieldMapper .NumberFieldType (NUMBER_FIELD_NAME , NumberFieldMapper .NumberType .INTEGER );
251+ MappedFieldType fieldType
252+ = new NumberFieldMapper .NumberFieldType (NUMBER_FIELD_NAME , NumberFieldMapper .NumberType .INTEGER );
254253
255- expectThrows (ElasticsearchParseException .class ,
256- () -> testCase (aggregationBuilder , new MatchAllDocsQuery (), iw -> {
257- iw .addDocument (singleton (new NumericDocValuesField (NUMBER_FIELD_NAME , 7 )));
258- iw .addDocument (singleton (new NumericDocValuesField (NUMBER_FIELD_NAME , 1 )));
259- }, range -> fail ("Should have thrown exception" ), fieldType ));
260- }
254+ expectThrows (ElasticsearchParseException .class ,
255+ () -> testCase (aggregationBuilder , new MatchAllDocsQuery (), iw -> {
256+ iw .addDocument (singleton (new NumericDocValuesField (NUMBER_FIELD_NAME , 7 )));
257+ iw .addDocument (singleton (new NumericDocValuesField (NUMBER_FIELD_NAME , 1 )));
258+ }, range -> fail ("Should have thrown exception" ), fieldType ));
259+ }
261260
262- private void testBothResolutions (Query query ,
263- CheckedConsumer <RandomIndexWriter , IOException > buildIndex ,
264- Consumer <InternalRange <? extends InternalRange .Bucket , ? extends InternalRange >> verify )
265- throws IOException {
266- testCase (query , buildIndex , verify , DateFieldMapper .Resolution .MILLISECONDS );
267- testCase (query , buildIndex , verify , DateFieldMapper .Resolution .NANOSECONDS );
261+ private void testBothResolutions (
262+ Query query ,
263+ CheckedBiConsumer <RandomIndexWriter , DateFieldMapper .Resolution , IOException > buildIndex ,
264+ Consumer <InternalRange <? extends InternalRange .Bucket , ? extends InternalRange >> verify
265+ ) throws IOException {
266+ testCase (
267+ query ,
268+ iw -> buildIndex .accept (iw , DateFieldMapper .Resolution .MILLISECONDS ),
269+ verify ,
270+ DateFieldMapper .Resolution .MILLISECONDS
271+ );
272+ testCase (
273+ query ,
274+ iw -> buildIndex .accept (iw , DateFieldMapper .Resolution .NANOSECONDS ),
275+ verify ,
276+ DateFieldMapper .Resolution .NANOSECONDS
277+ );
268278 }
269279
270280 private void testCase (Query query ,
0 commit comments