40
40
import java .util .ArrayList ;
41
41
import java .util .Arrays ;
42
42
import java .util .Collections ;
43
+ import java .util .Comparator ;
43
44
import java .util .List ;
44
45
import java .util .Map ;
45
46
import java .util .Objects ;
46
47
47
48
import static org .elasticsearch .index .query .AbstractQueryBuilder .parseInnerQueryBuilder ;
48
49
49
50
public class FiltersAggregationBuilder extends AbstractAggregationBuilder <FiltersAggregationBuilder >
50
- implements MultiBucketAggregationBuilder {
51
+ implements MultiBucketAggregationBuilder {
51
52
public static final String NAME = "filters" ;
52
53
53
54
private static final ParseField FILTERS_FIELD = new ParseField ("filters" );
@@ -74,7 +75,7 @@ private FiltersAggregationBuilder(String name, List<KeyedFilter> filters, boolea
74
75
this .filters = new ArrayList <>(filters );
75
76
if (keyed ) {
76
77
// internally we want to have a fixed order of filters, regardless of the order of the filters in the request
77
- Collections . sort ( this .filters , ( KeyedFilter kf1 , KeyedFilter kf2 ) -> kf1 . key (). compareTo ( kf2 . key () ));
78
+ this .filters . sort ( Comparator . comparing ( KeyedFilter :: key ));
78
79
this .keyed = true ;
79
80
} else {
80
81
this .keyed = false ;
@@ -220,9 +221,9 @@ protected AggregationBuilder doRewrite(QueryRewriteContext queryShardContext) th
220
221
221
222
@ Override
222
223
protected AggregatorFactory <?> doBuild (SearchContext context , AggregatorFactory <?> parent , Builder subFactoriesBuilder )
223
- throws IOException {
224
+ throws IOException {
224
225
return new FiltersAggregatorFactory (name , filters , keyed , otherBucket , otherBucketKey , context , parent ,
225
- subFactoriesBuilder , metaData );
226
+ subFactoriesBuilder , metaData );
226
227
}
227
228
228
229
@ Override
@@ -248,15 +249,15 @@ protected XContentBuilder internalXContent(XContentBuilder builder, Params param
248
249
}
249
250
250
251
public static FiltersAggregationBuilder parse (String aggregationName , XContentParser parser )
251
- throws IOException {
252
+ throws IOException {
252
253
253
- List <FiltersAggregator .KeyedFilter > keyedFilters = null ;
254
- List <QueryBuilder > nonKeyedFilters = null ;
254
+ List <FiltersAggregator .KeyedFilter > filters = new ArrayList <>();
255
255
256
- XContentParser .Token token = null ;
256
+ XContentParser .Token token ;
257
257
String currentFieldName = null ;
258
258
String otherBucketKey = null ;
259
259
Boolean otherBucket = null ;
260
+ boolean keyed = false ;
260
261
while ((token = parser .nextToken ()) != XContentParser .Token .END_OBJECT ) {
261
262
if (token == XContentParser .Token .FIELD_NAME ) {
262
263
currentFieldName = parser .currentName ();
@@ -265,61 +266,61 @@ public static FiltersAggregationBuilder parse(String aggregationName, XContentPa
265
266
otherBucket = parser .booleanValue ();
266
267
} else {
267
268
throw new ParsingException (parser .getTokenLocation (),
268
- "Unknown key for a " + token + " in [" + aggregationName + "]: [" + currentFieldName + "]." );
269
+ "Unknown key for a " + token + " in [" + aggregationName + "]: [" + currentFieldName + "]." );
269
270
}
270
271
} else if (token == XContentParser .Token .VALUE_STRING ) {
271
272
if (OTHER_BUCKET_KEY_FIELD .match (currentFieldName , parser .getDeprecationHandler ())) {
272
273
otherBucketKey = parser .text ();
273
274
} else {
274
275
throw new ParsingException (parser .getTokenLocation (),
275
- "Unknown key for a " + token + " in [" + aggregationName + "]: [" + currentFieldName + "]." );
276
+ "Unknown key for a " + token + " in [" + aggregationName + "]: [" + currentFieldName + "]." );
276
277
}
277
278
} else if (token == XContentParser .Token .START_OBJECT ) {
278
279
if (FILTERS_FIELD .match (currentFieldName , parser .getDeprecationHandler ())) {
279
- keyedFilters = new ArrayList <>();
280
280
String key = null ;
281
281
while ((token = parser .nextToken ()) != XContentParser .Token .END_OBJECT ) {
282
282
if (token == XContentParser .Token .FIELD_NAME ) {
283
283
key = parser .currentName ();
284
284
} else {
285
285
QueryBuilder filter = parseInnerQueryBuilder (parser );
286
- keyedFilters .add (new FiltersAggregator .KeyedFilter (key , filter ));
286
+ filters .add (new FiltersAggregator .KeyedFilter (key , filter ));
287
287
}
288
288
}
289
+ keyed = true ;
289
290
} else {
290
291
throw new ParsingException (parser .getTokenLocation (),
291
- "Unknown key for a " + token + " in [" + aggregationName + "]: [" + currentFieldName + "]." );
292
+ "Unknown key for a " + token + " in [" + aggregationName + "]: [" + currentFieldName + "]." );
292
293
}
293
294
} else if (token == XContentParser .Token .START_ARRAY ) {
294
295
if (FILTERS_FIELD .match (currentFieldName , parser .getDeprecationHandler ())) {
295
- nonKeyedFilters = new ArrayList <>();
296
- while (( token = parser .nextToken () ) != XContentParser .Token .END_ARRAY ) {
296
+ List < QueryBuilder > builders = new ArrayList <>();
297
+ while (parser .nextToken () != XContentParser .Token .END_ARRAY ) {
297
298
QueryBuilder filter = parseInnerQueryBuilder (parser );
298
- nonKeyedFilters .add (filter );
299
+ builders .add (filter );
300
+ }
301
+ for (int i = 0 ; i < builders .size (); i ++) {
302
+ filters .add (new KeyedFilter (String .valueOf (i ), builders .get (i )));
299
303
}
300
304
} else {
301
305
throw new ParsingException (parser .getTokenLocation (),
302
- "Unknown key for a " + token + " in [" + aggregationName + "]: [" + currentFieldName + "]." );
306
+ "Unknown key for a " + token + " in [" + aggregationName + "]: [" + currentFieldName + "]." );
303
307
}
304
308
} else {
305
309
throw new ParsingException (parser .getTokenLocation (),
306
- "Unknown key for a " + token + " in [" + aggregationName + "]: [" + currentFieldName + "]." );
310
+ "Unknown key for a " + token + " in [" + aggregationName + "]: [" + currentFieldName + "]." );
307
311
}
308
312
}
309
313
314
+ if (filters .isEmpty ()) {
315
+ throw new IllegalArgumentException ("[" + FILTERS_FIELD + "] cannot be empty." );
316
+ }
317
+
318
+ FiltersAggregationBuilder factory = new FiltersAggregationBuilder (aggregationName , filters , keyed );
319
+
310
320
if (otherBucket == null && otherBucketKey != null ) {
311
321
// automatically enable the other bucket if a key is set, as per the doc
312
322
otherBucket = true ;
313
323
}
314
-
315
- FiltersAggregationBuilder factory ;
316
- if (keyedFilters != null ) {
317
- factory = new FiltersAggregationBuilder (aggregationName ,
318
- keyedFilters .toArray (new FiltersAggregator .KeyedFilter [keyedFilters .size ()]));
319
- } else {
320
- factory = new FiltersAggregationBuilder (aggregationName ,
321
- nonKeyedFilters .toArray (new QueryBuilder [nonKeyedFilters .size ()]));
322
- }
323
324
if (otherBucket != null ) {
324
325
factory .otherBucket (otherBucket );
325
326
}
@@ -338,9 +339,9 @@ protected int doHashCode() {
338
339
protected boolean doEquals (Object obj ) {
339
340
FiltersAggregationBuilder other = (FiltersAggregationBuilder ) obj ;
340
341
return Objects .equals (filters , other .filters )
341
- && Objects .equals (keyed , other .keyed )
342
- && Objects .equals (otherBucket , other .otherBucket )
343
- && Objects .equals (otherBucketKey , other .otherBucketKey );
342
+ && Objects .equals (keyed , other .keyed )
343
+ && Objects .equals (otherBucket , other .otherBucket )
344
+ && Objects .equals (otherBucketKey , other .otherBucketKey );
344
345
}
345
346
346
347
@ Override
0 commit comments