DATAES-180 - added faceted page back powered by aggregation

This commit is contained in:
Artur Konczak
2016-05-31 16:47:48 +01:00
parent 6ffac62b3e
commit 392a87ab0a
8 changed files with 122 additions and 216 deletions

View File

@@ -24,11 +24,15 @@ import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.range.Range;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.stats.Stats;
import org.elasticsearch.search.aggregations.metrics.stats.extended.ExtendedStats;
import org.elasticsearch.search.aggregations.metrics.sum.Sum;
import org.joda.time.DateTime;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.facet.AbstractFacetRequest;
import org.springframework.data.elasticsearch.core.facet.FacetResult;
import org.springframework.data.elasticsearch.core.facet.request.RangeFacetRequest;
import org.springframework.data.elasticsearch.core.facet.result.*;
/**
@@ -88,24 +92,35 @@ public abstract class FacetedPageImpl<T> extends PageImpl<T> implements FacetedP
for (Terms.Bucket t : ((Terms) agg).getBuckets()) {
terms.add(new Term(t.getKeyAsString(), t.getDocCount()));
}
addFacet(new TermResult(agg.getName(), terms, terms.size(), ((Terms) agg).getSumOfOtherDocCounts(), -1));
addFacet(new TermResult(agg.getName(), terms, terms.size(), ((Terms) agg).getSumOfOtherDocCounts(), 0));
}
if (agg instanceof Range) {
List<? extends Range.Bucket> buckets = ((Range) agg).getBuckets();
List<org.springframework.data.elasticsearch.core.facet.result.Range> ranges = new ArrayList<org.springframework.data.elasticsearch.core.facet.result.Range>();
for (Range.Bucket b : buckets) {
ranges.add(new org.springframework.data.elasticsearch.core.facet.result.Range((Double) b.getFrom(), (Double) b.getTo(), b.getDocCount(), 0, 0, 0, 0));
ExtendedStats rStats = (ExtendedStats) b.getAggregations().get(AbstractFacetRequest.INTERNAL_STATS);
if (rStats != null) {
Sum sum = (Sum) b.getAggregations().get(RangeFacetRequest.RANGE_INTERNAL_SUM);
ranges.add(new org.springframework.data.elasticsearch.core.facet.result.Range((Double) b.getFrom(), (Double) b.getTo(), b.getDocCount(), sum != null ? sum.getValue() : rStats.getSum(), rStats.getCount(), rStats.getMin(), rStats.getMax()));
} else {
ranges.add(new org.springframework.data.elasticsearch.core.facet.result.Range((Double) b.getFrom(), (Double) b.getTo(), b.getDocCount(), 0, 0, 0, 0));
}
}
addFacet(new RangeResult(agg.getName(), ranges));
}
if (agg instanceof Stats) {
Stats stats = (Stats) agg;
addFacet(new StatisticalResult(agg.getName(), stats.getCount(), stats.getMax(), stats.getMin(), stats.getAvg(), -1, -1, stats.getSum(), -1));
if (agg instanceof ExtendedStats) {
ExtendedStats stats = (ExtendedStats) agg;
addFacet(new StatisticalResult(agg.getName(), stats.getCount(), stats.getMax(), stats.getMin(), stats.getAvg(), stats.getStdDeviation(), stats.getSumOfSquares(), stats.getSum(), stats.getVariance()));
}
if (agg instanceof Histogram) {
List<IntervalUnit> intervals = new ArrayList<IntervalUnit>();
for (Histogram.Bucket h : ((Histogram) agg).getBuckets()) {
new IntervalUnit((Long) h.getKey(), h.getDocCount(), h.getDocCount(), -1, -1, -1, -1);
ExtendedStats hStats = (ExtendedStats) h.getAggregations().get(AbstractFacetRequest.INTERNAL_STATS);
if (hStats != null) {
intervals.add(new IntervalUnit(((DateTime) h.getKey()).getMillis(), h.getDocCount(), h.getDocCount(), hStats.getSum(), hStats.getAvg(), hStats.getMin(), hStats.getMax()));
} else {
intervals.add(new IntervalUnit(((DateTime) h.getKey()).getMillis(), h.getDocCount(), h.getDocCount(), 0, 0, 0, 0));
}
}
addFacet(new HistogramResult(agg.getName(), intervals));
}

View File

@@ -25,6 +25,8 @@ import org.springframework.util.Assert;
@Deprecated
public abstract class AbstractFacetRequest implements FacetRequest {
public static final String INTERNAL_STATS = "internal-stats";
private String name;
private boolean applyQueryFilter;

View File

@@ -1,81 +0,0 @@
///*
// * Copyright 2014 the original author or authors.
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
//package org.springframework.data.elasticsearch.core.facet;
//
//import java.util.ArrayList;
//import java.util.List;
//
//import org.elasticsearch.search.facet.Facet;
//import org.elasticsearch.search.facet.histogram.HistogramFacet;
//import org.elasticsearch.search.facet.range.RangeFacet;
//import org.elasticsearch.search.facet.statistical.StatisticalFacet;
//import org.elasticsearch.search.facet.terms.TermsFacet;
//import org.springframework.data.elasticsearch.core.facet.result.*;
//
///**
// * @author Artur Konczak
// * @author Petar Tahchiev
// */
//public class DefaultFacetMapper {
//
// public static FacetResult parse(Facet facet) {
// if (facet instanceof TermsFacet) {
// return parseTerm((TermsFacet) facet);
// }
//
// if (facet instanceof RangeFacet) {
// return parseRange((RangeFacet) facet);
// }
//
// if (facet instanceof StatisticalFacet) {
// return parseStatistical((StatisticalFacet) facet);
// }
//
// if (facet instanceof HistogramFacet) {
// return parseHistogram((HistogramFacet) facet);
// }
//
// return null;
// }
//
// private static FacetResult parseTerm(TermsFacet facet) {
// List<Term> entries = new ArrayList<Term>();
// for (TermsFacet.Entry entry : facet.getEntries()) {
// entries.add(new Term(entry.getTerm().toString(), entry.getCount()));
// }
// return new TermResult(facet.getName(), entries, facet.getTotalCount(), facet.getOtherCount(), facet.getMissingCount());
// }
//
// private static FacetResult parseRange(RangeFacet facet) {
// List<Range> entries = new ArrayList<Range>();
// for (RangeFacet.Entry entry : facet.getEntries()) {
// entries.add(new Range(entry.getFrom() == Double.NEGATIVE_INFINITY ? null : entry.getFrom(), entry.getTo() == Double.POSITIVE_INFINITY ? null : entry.getTo(), entry.getCount(), entry.getTotal(), entry.getTotalCount(), entry.getMin(), entry.getMax()));
// }
// return new RangeResult(facet.getName(), entries);
// }
//
// private static FacetResult parseStatistical(StatisticalFacet facet) {
// return new StatisticalResult(facet.getName(), facet.getCount(), facet.getMax(), facet.getMin(), facet.getMean(), facet.getStdDeviation(), facet.getSumOfSquares(), facet.getTotal(), facet.getVariance());
// }
//
// private static FacetResult parseHistogram(HistogramFacet facet) {
// List<IntervalUnit> entries = new ArrayList<IntervalUnit>();
// for (HistogramFacet.Entry entry : facet.getEntries()) {
// entries.add(new IntervalUnit(entry.getKey(), entry.getCount(), entry.getTotalCount(), entry.getTotal(), entry.getMean(), entry.getMin(), entry.getMax()));
// }
// return new HistogramResult(facet.getName(), entries);
// }
//}

View File

@@ -66,6 +66,8 @@ public class HistogramFacetRequest extends AbstractFacetRequest {
dateHistogramBuilder.interval(interval);
}
dateHistogramBuilder.subAggregation(AggregationBuilders.extendedStats(INTERNAL_STATS));
return dateHistogramBuilder;
}
}

View File

@@ -19,6 +19,7 @@ package org.springframework.data.elasticsearch.core.facet.request;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.range.RangeBuilder;
@@ -35,6 +36,7 @@ import org.springframework.util.Assert;
@Deprecated
public class RangeFacetRequest extends AbstractFacetRequest {
public static final String RANGE_INTERNAL_SUM = "range-internal-sum";
private String field;
private String keyField;
private String valueField;
@@ -50,7 +52,8 @@ public class RangeFacetRequest extends AbstractFacetRequest {
}
public void setFields(String keyField, String valueField) {
throw new UnsupportedOperationException("Native Facet are not supported in Elasticsearch 2.x - use Aggregation");
this.keyField = keyField;
this.valueField = valueField;
}
public void range(Double from, Double to) {
@@ -74,13 +77,18 @@ public class RangeFacetRequest extends AbstractFacetRequest {
Assert.notNull(getName(), "Facet name can't be a null !!!");
RangeBuilder rangeBuilder = AggregationBuilders.range(getName());
rangeBuilder.field(field);
rangeBuilder.field(StringUtils.isNotBlank(keyField) ? keyField : field );
for (Entry entry : entries) {
DoubleEntry doubleEntry = (DoubleEntry) entry;
rangeBuilder.addRange(validateValue(doubleEntry.getFrom(), Double.NEGATIVE_INFINITY), validateValue(doubleEntry.getTo(), Double.POSITIVE_INFINITY));
}
rangeBuilder.subAggregation(AggregationBuilders.extendedStats(INTERNAL_STATS));
if(StringUtils.isNotBlank(valueField)){
rangeBuilder.subAggregation(AggregationBuilders.sum(RANGE_INTERNAL_SUM).field(valueField));
}
return rangeBuilder;
}

View File

@@ -48,6 +48,6 @@ public class StatisticalFacetRequest extends AbstractFacetRequest {
public AbstractAggregationBuilder getFacet() {
Assert.notNull(getName(), "Facet name can't be a null !!!");
Assert.isTrue(StringUtils.isNotBlank(field) && fields == null, "Please select field or fields on which to build the facets !!!");
return AggregationBuilders.stats(getName()).field(field);
return AggregationBuilders.extendedStats(getName()).field(field);
}
}

View File

@@ -46,8 +46,8 @@ public class TermFacetRequest extends AbstractFacetRequest {
}
public void setFields(String... fields) {
Assert.isTrue(ArrayUtils.isNotEmpty(fields), "Term agg need one field");
Assert.isTrue(ArrayUtils.getLength(fields) == 1, "Term agg need one field");
Assert.isTrue(ArrayUtils.isNotEmpty(fields), "Term agg need one field only");
Assert.isTrue(ArrayUtils.getLength(fields) == 1, "Term agg need one field only");
this.fields = fields;
}
@@ -84,11 +84,11 @@ public class TermFacetRequest extends AbstractFacetRequest {
case ascTerm:
termsBuilder.order(Terms.Order.term(true));
break;
case ascCount:
termsBuilder.order(Terms.Order.count(true));
case descCount:
termsBuilder.order(Terms.Order.count(false));
break;
default:
termsBuilder.order(Terms.Order.count(false));
termsBuilder.order(Terms.Order.count(true));
}
if (ArrayUtils.isNotEmpty(excludeTerms)) {
termsBuilder.exclude(excludeTerms);