@SuppressWarnings("unchecked") @Override public InternalAggregation reduce(InternalAggregation aggregation, ReduceContext reduceContext) { if (aggregation instanceof InternalMultiBucketAggregation) { @SuppressWarnings("rawtypes") InternalMultiBucketAggregation multiBucketsAgg = (InternalMultiBucketAggregation) aggregation; List<? extends Bucket> buckets = multiBucketsAgg.getBuckets(); List<Bucket> newBuckets = new ArrayList<>(); for (int i = 0; i < buckets.size(); i++) { InternalMultiBucketAggregation.InternalBucket bucket = (InternalMultiBucketAggregation.InternalBucket) buckets.get(i); InternalAggregation aggToAdd = doReduce(bucket.getAggregations(), reduceContext); List<InternalAggregation> aggs = StreamSupport.stream(bucket.getAggregations().spliterator(), false) .map( (p) -> { return (InternalAggregation) p; }) .collect(Collectors.toList()); aggs.add(aggToAdd); InternalMultiBucketAggregation.InternalBucket newBucket = multiBucketsAgg.createBucket(new InternalAggregations(aggs), bucket); newBuckets.add(newBucket); } return multiBucketsAgg.create(newBuckets); } else if (aggregation instanceof InternalSingleBucketAggregation) { InternalSingleBucketAggregation singleBucketAgg = (InternalSingleBucketAggregation) aggregation; InternalAggregation aggToAdd = doReduce(singleBucketAgg.getAggregations(), reduceContext); List<InternalAggregation> aggs = StreamSupport.stream(singleBucketAgg.getAggregations().spliterator(), false) .map( (p) -> { return (InternalAggregation) p; }) .collect(Collectors.toList()); aggs.add(aggToAdd); return singleBucketAgg.create(new InternalAggregations(aggs)); } else { throw new IllegalStateException( "Aggregation [" + aggregation.getName() + "] must be a bucket aggregation [" + aggregation.type().name() + "]"); } }
@Override public InternalAggregation reduce(InternalAggregation aggregation, ReduceContext reduceContext) { InternalMultiBucketAggregation< InternalMultiBucketAggregation, InternalMultiBucketAggregation.InternalBucket> originalAgg = (InternalMultiBucketAggregation< InternalMultiBucketAggregation, InternalMultiBucketAggregation.InternalBucket>) aggregation; List<? extends Bucket> buckets = originalAgg.getBuckets(); CompiledScript compiledScript = reduceContext.scriptService().compile(script, ScriptContext.Standard.AGGS, reduceContext); List newBuckets = new ArrayList<>(); for (Bucket bucket : buckets) { Map<String, Object> vars = new HashMap<>(); if (script.getParams() != null) { vars.putAll(script.getParams()); } boolean skipBucket = false; for (Map.Entry<String, String> entry : bucketsPathsMap.entrySet()) { String varName = entry.getKey(); String bucketsPath = entry.getValue(); Double value = resolveBucketValue(originalAgg, bucket, bucketsPath, gapPolicy); if (GapPolicy.SKIP == gapPolicy && (value == null || Double.isNaN(value))) { skipBucket = true; break; } vars.put(varName, value); } if (skipBucket) { newBuckets.add(bucket); } else { ExecutableScript executableScript = reduceContext.scriptService().executable(compiledScript, vars); Object returned = executableScript.run(); if (returned == null) { newBuckets.add(bucket); } else { if (!(returned instanceof Number)) { throw new AggregationExecutionException( "series_arithmetic script for reducer [" + name() + "] must return a Number"); } List<InternalAggregation> aggs = new ArrayList<>(eagerTransform(bucket.getAggregations().asList(), FUNCTION)); aggs.add( new InternalSimpleValue( name(), ((Number) returned).doubleValue(), formatter, new ArrayList<PipelineAggregator>(), metaData())); InternalMultiBucketAggregation.InternalBucket newBucket = originalAgg.createBucket( new InternalAggregations(aggs), (InternalMultiBucketAggregation.InternalBucket) bucket); newBuckets.add(newBucket); } } } return originalAgg.create(newBuckets); }