package com.github.obourgain.elasticsearch.http.response.entity.aggs;
import static org.elasticsearch.common.xcontent.XContentParser.Token.END_OBJECT;
import static org.elasticsearch.common.xcontent.XContentParser.Token.FIELD_NAME;
import static org.elasticsearch.common.xcontent.XContentParser.Token.START_OBJECT;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.tuple.Pair;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentParser.Token;
import org.elasticsearch.common.xcontent.XContentType;
import com.github.obourgain.elasticsearch.http.response.entity.Converter;
@SuppressWarnings("unused")
public class Aggregations {
private final Map<String, Aggregation> parsed = new HashMap<>();
private final Map<String, XContentBuilder> rawAggs = new HashMap<>();
public Collection<String> names() {
return rawAggs.keySet();
}
public Terms getTerms(final String name) {
return findOrCreate(name, new Converter<Terms>() {
@Override
public Terms convert(XContentParser parser) {
return Terms.parse(parser, name);
}
});
}
public Min getMin(final String name) {
return findOrCreate(name, new Converter<Min>() {
@Override
public Min convert(XContentParser parser) {
return new Min().parse(parser, name);
}
});
}
public Max getMax(final String name) {
return findOrCreate(name, new Converter<Max>() {
@Override
public Max convert(XContentParser parser) {
return new Max().parse(parser, name);
}
});
}
public Avg getAvg(final String name) {
return findOrCreate(name, new Converter<Avg>() {
@Override
public Avg convert(XContentParser parser) {
return new Avg().parse(parser, name);
}
});
}
public Sum getSum(final String name) {
return findOrCreate(name, new Converter<Sum>() {
@Override
public Sum convert(XContentParser parser) {
return new Sum().parse(parser, name);
}
});
}
public Stats getStats(final String name) {
return findOrCreate(name, new Converter<Stats>() {
@Override
public Stats convert(XContentParser parser) {
return Stats.parse(parser, name);
}
});
}
public ExtendedStats getExtendedStats(final String name) {
return findOrCreate(name, new Converter<ExtendedStats>() {
@Override
public ExtendedStats convert(XContentParser parser) {
return ExtendedStats.parse(parser, name);
}
});
}
public ValueCount getValueCount(final String name) {
return findOrCreate(name, new Converter<ValueCount>() {
@Override
public ValueCount convert(XContentParser parser) {
return new ValueCount().parse(parser, name);
}
});
}
public Percentiles getPercentiles(final String name) {
return findOrCreate(name, new Converter<Percentiles>() {
@Override
public Percentiles convert(XContentParser parser) {
return new Percentiles().parse(parser, name);
}
});
}
public PercentileRanks getPercentileRanks(final String name) {
return findOrCreate(name, new Converter<PercentileRanks>() {
@Override
public PercentileRanks convert(XContentParser parser) {
return new PercentileRanks().parse(parser, name);
}
});
}
public Cardinality getCardinality(final String name) {
return findOrCreate(name, new Converter<Cardinality>() {
@Override
public Cardinality convert(XContentParser parser) {
return new Cardinality().parse(parser, name);
}
});
}
public GeoBounds getGeoBounds(final String name) {
return findOrCreate(name, new Converter<GeoBounds>() {
@Override
public GeoBounds convert(XContentParser parser) {
return GeoBounds.parse(parser, name);
}
});
}
public TopHits getTopHits(final String name) {
return findOrCreate(name, new Converter<TopHits>() {
@Override
public TopHits convert(XContentParser parser) {
return TopHits.parse(parser, name);
}
});
}
public ScriptedMetric getScriptedMetric(final String name) {
return findOrCreate(name, new Converter<ScriptedMetric>() {
@Override
public ScriptedMetric convert(XContentParser parser) {
return ScriptedMetric.parse(parser, name);
}
});
}
public Global getGlobal(final String name) {
return findOrCreate(name, new Converter<Global>() {
@Override
public Global convert(XContentParser parser) {
return new Global().parse(parser, name);
}
});
}
public Filter getFilter(final String name) {
return findOrCreate(name, new Converter<Filter>() {
@Override
public Filter convert(XContentParser parser) {
return new Filter().parse(parser, name);
}
});
}
public Filters getFilters(final String name) {
return findOrCreate(name, new Converter<Filters>() {
@Override
public Filters convert(XContentParser parser) {
return Filters.parse(parser, name);
}
});
}
public Missing getMissing(final String name) {
return findOrCreate(name, new Converter<Missing>() {
@Override
public Missing convert(XContentParser parser) {
return new Missing().parse(parser, name);
}
});
}
public Nested getNested(final String name) {
return findOrCreate(name, new Converter<Nested>() {
@Override
public Nested convert(XContentParser parser) {
return new Nested().parse(parser, name);
}
});
}
public ReverseNested getReverseNested(final String name) {
return findOrCreate(name, new Converter<ReverseNested>() {
@Override
public ReverseNested convert(XContentParser parser) {
return new ReverseNested().parse(parser, name);
}
});
}
public Children getChildren(final String name) {
return findOrCreate(name, new Converter<Children>() {
@Override
public Children convert(XContentParser parser) {
return new Children().parse(parser, name);
}
});
}
public SignificantTerms getSignificantTerms(final String name) {
return findOrCreate(name, new Converter<SignificantTerms>() {
@Override
public SignificantTerms convert(XContentParser parser) {
return SignificantTerms.parse(parser, name);
}
});
}
public Range getRange(final String name) {
return findOrCreate(name, new Converter<Range>() {
@Override
public Range convert(XContentParser parser) {
return new Range().parse(parser, name);
}
});
}
public DateRange getDateRange(final String name) {
return findOrCreate(name, new Converter<DateRange>() {
@Override
public DateRange convert(XContentParser parser) {
return new DateRange().parse(parser, name);
}
});
}
public IPV4Range getIPV4Range(final String name) {
return findOrCreate(name, new Converter<IPV4Range>() {
@Override
public IPV4Range convert(XContentParser parser) {
return new IPV4Range().parse(parser, name);
}
});
}
public Histogram getHistogram(final String name) {
return findOrCreate(name, new Converter<Histogram>() {
@Override
public Histogram convert(XContentParser parser) {
return new Histogram().parse(parser, name);
}
});
}
public DateHistogram getDateHistogram(final String name) {
return findOrCreate(name, new Converter<DateHistogram>() {
@Override
public DateHistogram convert(XContentParser parser) {
return new DateHistogram().parse(parser, name);
}
});
}
public GeoDistance getGeoDistance(final String name) {
return findOrCreate(name, new Converter<GeoDistance>() {
@Override
public GeoDistance convert(XContentParser parser) {
return GeoDistance.parse(parser, name);
}
});
}
public GeoHash getGeoHash(final String name) {
return findOrCreate(name, new Converter<GeoHash>() {
@Override
public GeoHash convert(XContentParser parser) {
return GeoHash.parse(parser, name);
}
});
}
private <T extends Aggregation> T findOrCreate(String name, Converter<T> converter) {
@SuppressWarnings("unchecked")
T t = (T) parsed.get(name);
if (t != null) {
return t;
} else {
XContentBuilder builder = rawAggs.get(name);
try {
if (builder != null) {
try (XContentParser parser = XContentHelper.createParser(builder.bytes())) {
t = converter.convert(parser);
parsed.put(name, t);
return t;
}
} else {
return null;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
protected void addRawAgg(String name, XContentBuilder rawAgg) {
rawAggs.put(name, rawAgg);
}
/*
parses something like : (with the heading parenthesis)
{
"grades_stats": {
"count": 6,
"min": 60,
"max": 98,
"avg": 78.5,
"sum": 471
}
}
*/
public static Aggregations parse(XContentParser parser) {
try {
assert parser.currentToken() == START_OBJECT : "expected a START_OBJECT token but was " + parser.currentToken();
Aggregations aggregations = new Aggregations();
Token token;
String currentFieldName = null;
while ((token = parser.nextToken()) != END_OBJECT) {
if (token == FIELD_NAME) {
currentFieldName = parser.currentName();
} else if (token == START_OBJECT) {
try (XContentBuilder docBuilder = XContentFactory.contentBuilder(XContentType.JSON)) {
aggregations.addRawAgg(currentFieldName, docBuilder.copyCurrentStructure(parser));
}
}
}
return aggregations;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/*
parses something like (e.g. for sub aggs)
"avg_price" : {
"value" : 56.3
}
*/
protected static Pair<String, XContentBuilder> parseInnerAgg(XContentParser parser, String aggregationName) {
try {
assert parser.currentToken() == START_OBJECT : "expected a START_OBJECT token but was " + parser.currentToken();
XContentBuilder docBuilder = XContentFactory.contentBuilder(XContentType.JSON);
docBuilder.copyCurrentStructure(parser);
docBuilder.close();
return Pair.of(aggregationName, docBuilder);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public String toString() {
return "Aggregations{" +
"knownAggregations=" + rawAggs.keySet() +
'}';
}
}