mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-07-08 11:32:45 +00:00
DATAES-21 statistical facets(Petar Tahchiev)
This commit is contained in:
parent
99940f47c3
commit
35cb4e6930
@ -1,18 +1,18 @@
|
|||||||
package org.springframework.data.elasticsearch.core.facet;
|
package org.springframework.data.elasticsearch.core.facet;
|
||||||
|
|
||||||
import org.elasticsearch.search.facet.Facet;
|
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.range.RangeFacet;
|
||||||
|
import org.elasticsearch.search.facet.statistical.StatisticalFacet;
|
||||||
import org.elasticsearch.search.facet.terms.TermsFacet;
|
import org.elasticsearch.search.facet.terms.TermsFacet;
|
||||||
import org.springframework.data.elasticsearch.core.facet.result.Range;
|
import org.springframework.data.elasticsearch.core.facet.result.*;
|
||||||
import org.springframework.data.elasticsearch.core.facet.result.RangeResult;
|
|
||||||
import org.springframework.data.elasticsearch.core.facet.result.Term;
|
|
||||||
import org.springframework.data.elasticsearch.core.facet.result.TermResult;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Artur Konczak
|
* @author Artur Konczak
|
||||||
|
* @author Petar Tahchiev
|
||||||
*/
|
*/
|
||||||
public class FacetMapper {
|
public class FacetMapper {
|
||||||
|
|
||||||
@ -25,6 +25,10 @@ public class FacetMapper {
|
|||||||
return parseRange((RangeFacet) facet);
|
return parseRange((RangeFacet) facet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (facet instanceof StatisticalFacet) {
|
||||||
|
return parseStatistical((StatisticalFacet) facet);
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,4 +48,8 @@ public class FacetMapper {
|
|||||||
return new RangeResult(facet.getName(), entries);
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
package org.springframework.data.elasticsearch.core.facet;
|
package org.springframework.data.elasticsearch.core.facet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Artur Konczak
|
||||||
|
* @author Petar Tahchiev
|
||||||
|
*/
|
||||||
public enum FacetType {
|
public enum FacetType {
|
||||||
|
|
||||||
term, range, histogram
|
term, range, histogram, statistical
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package org.springframework.data.elasticsearch.core.facet.request;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.ArrayUtils;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.elasticsearch.search.facet.FacetBuilder;
|
||||||
|
import org.elasticsearch.search.facet.FacetBuilders;
|
||||||
|
import org.elasticsearch.search.facet.statistical.StatisticalFacetBuilder;
|
||||||
|
import org.springframework.data.elasticsearch.core.facet.AbstractFacetRequest;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Petar Tahchiev
|
||||||
|
*/
|
||||||
|
public class StatisticalFacetRequest extends AbstractFacetRequest {
|
||||||
|
|
||||||
|
private String field;
|
||||||
|
|
||||||
|
private String[] fields;
|
||||||
|
|
||||||
|
public StatisticalFacetRequest(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setField(String field) {
|
||||||
|
this.field = field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFields(String... fields) {
|
||||||
|
this.fields = fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FacetBuilder 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 !!!");
|
||||||
|
|
||||||
|
StatisticalFacetBuilder builder = FacetBuilders.statisticalFacet(getName());
|
||||||
|
if (ArrayUtils.isNotEmpty(fields)) {
|
||||||
|
builder.fields(fields);
|
||||||
|
} else {
|
||||||
|
builder.field(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package org.springframework.data.elasticsearch.core.facet.request;
|
||||||
|
|
||||||
|
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Petar Tahchiev
|
||||||
|
*/
|
||||||
|
public class StatisticalFacetRequestBuilder {
|
||||||
|
|
||||||
|
StatisticalFacetRequest result;
|
||||||
|
|
||||||
|
public StatisticalFacetRequestBuilder(String name) {
|
||||||
|
result = new StatisticalFacetRequest(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatisticalFacetRequestBuilder field(String field) {
|
||||||
|
result.setField(field);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatisticalFacetRequestBuilder fields(String... fields) {
|
||||||
|
result.setFields(fields);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StatisticalFacetRequestBuilder applyQueryFilter() {
|
||||||
|
result.setApplyQueryFilter(true);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FacetRequest build() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
package org.springframework.data.elasticsearch.core.facet.result;
|
||||||
|
|
||||||
|
import org.springframework.data.elasticsearch.core.facet.AbstactFacetResult;
|
||||||
|
import org.springframework.data.elasticsearch.core.facet.FacetType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Petar Tahchiev
|
||||||
|
*/
|
||||||
|
public class StatisticalResult extends AbstactFacetResult {
|
||||||
|
|
||||||
|
private long count;
|
||||||
|
|
||||||
|
private double max;
|
||||||
|
|
||||||
|
private double min;
|
||||||
|
|
||||||
|
private double mean;
|
||||||
|
|
||||||
|
private double stdDeviation;
|
||||||
|
|
||||||
|
private double sumOfSquares;
|
||||||
|
|
||||||
|
private double total;
|
||||||
|
|
||||||
|
private double variance;
|
||||||
|
|
||||||
|
public StatisticalResult(String name, long count, double max, double min, double mean, double stdDeviation, double sumOfSquares, double total, double variance) {
|
||||||
|
super(name, FacetType.statistical);
|
||||||
|
this.count = count;
|
||||||
|
this.max = max;
|
||||||
|
this.min = min;
|
||||||
|
this.mean = mean;
|
||||||
|
this.stdDeviation = stdDeviation;
|
||||||
|
this.sumOfSquares = sumOfSquares;
|
||||||
|
this.total = total;
|
||||||
|
this.variance = variance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCount() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMax() {
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMin() {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMean() {
|
||||||
|
return mean;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getStdDeviation() {
|
||||||
|
return stdDeviation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getSumOfSquares() {
|
||||||
|
return sumOfSquares;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getTotal() {
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getVariance() {
|
||||||
|
return variance;
|
||||||
|
}
|
||||||
|
}
|
@ -23,13 +23,8 @@ import org.junit.runner.RunWith;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
|
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
|
||||||
import org.springframework.data.elasticsearch.core.FacetedPage;
|
import org.springframework.data.elasticsearch.core.FacetedPage;
|
||||||
import org.springframework.data.elasticsearch.core.facet.request.NativeFacetRequest;
|
import org.springframework.data.elasticsearch.core.facet.request.*;
|
||||||
import org.springframework.data.elasticsearch.core.facet.request.RangeFacetRequestBuilder;
|
import org.springframework.data.elasticsearch.core.facet.result.*;
|
||||||
import org.springframework.data.elasticsearch.core.facet.request.TermFacetRequestBuilder;
|
|
||||||
import org.springframework.data.elasticsearch.core.facet.result.Range;
|
|
||||||
import org.springframework.data.elasticsearch.core.facet.result.RangeResult;
|
|
||||||
import org.springframework.data.elasticsearch.core.facet.result.Term;
|
|
||||||
import org.springframework.data.elasticsearch.core.facet.result.TermResult;
|
|
||||||
import org.springframework.data.elasticsearch.core.query.IndexQuery;
|
import org.springframework.data.elasticsearch.core.query.IndexQuery;
|
||||||
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
||||||
import org.springframework.data.elasticsearch.core.query.SearchQuery;
|
import org.springframework.data.elasticsearch.core.query.SearchQuery;
|
||||||
@ -57,6 +52,7 @@ public class ElasticsearchTemplateFacetTests {
|
|||||||
public static final int YEAR_2002 = 2002;
|
public static final int YEAR_2002 = 2002;
|
||||||
public static final int YEAR_2001 = 2001;
|
public static final int YEAR_2001 = 2001;
|
||||||
public static final int YEAR_2000 = 2000;
|
public static final int YEAR_2000 = 2000;
|
||||||
|
public static final String PUBLISHED_YEARS = "publishedYears";
|
||||||
@Autowired
|
@Autowired
|
||||||
private ElasticsearchTemplate elasticsearchTemplate;
|
private ElasticsearchTemplate elasticsearchTemplate;
|
||||||
|
|
||||||
@ -419,7 +415,7 @@ public class ElasticsearchTemplateFacetTests {
|
|||||||
String facetName = "rangeYears";
|
String facetName = "rangeYears";
|
||||||
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
|
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
|
||||||
.withFacet(
|
.withFacet(
|
||||||
new RangeFacetRequestBuilder(facetName).field("publishedYears")
|
new RangeFacetRequestBuilder(facetName).field(PUBLISHED_YEARS)
|
||||||
.to(YEAR_2000).range(YEAR_2000, YEAR_2002).from(YEAR_2002).build()
|
.to(YEAR_2000).range(YEAR_2000, YEAR_2002).from(YEAR_2002).build()
|
||||||
).build();
|
).build();
|
||||||
// when
|
// when
|
||||||
@ -456,7 +452,7 @@ public class ElasticsearchTemplateFacetTests {
|
|||||||
String facetName = "rangeScoreOverYears";
|
String facetName = "rangeScoreOverYears";
|
||||||
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
|
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
|
||||||
.withFacet(
|
.withFacet(
|
||||||
new RangeFacetRequestBuilder(facetName).fields("publishedYears", "score")
|
new RangeFacetRequestBuilder(facetName).fields(PUBLISHED_YEARS, "score")
|
||||||
.to(YEAR_2000).range(YEAR_2000, YEAR_2002).from(YEAR_2002).build()
|
.to(YEAR_2000).range(YEAR_2000, YEAR_2002).from(YEAR_2002).build()
|
||||||
).build();
|
).build();
|
||||||
// when
|
// when
|
||||||
@ -487,5 +483,21 @@ public class ElasticsearchTemplateFacetTests {
|
|||||||
assertThat(range.getTotal(), is(40.0));
|
assertThat(range.getTotal(), is(40.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReturnStatisticalFacetForGivenQuery() {
|
||||||
|
// given
|
||||||
|
String facetName = "statPublishedYear";
|
||||||
|
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
|
||||||
|
.withFacet(new StatisticalFacetRequestBuilder(facetName).field(PUBLISHED_YEARS).build()
|
||||||
|
).build();
|
||||||
|
// when
|
||||||
|
FacetedPage<ArticleEntity> result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class);
|
||||||
|
// then
|
||||||
|
assertThat(result.getNumberOfElements(), is(equalTo(4)));
|
||||||
|
|
||||||
|
StatisticalResult facet = (StatisticalResult) result.getFacet(facetName);
|
||||||
|
assertThat(facet.getCount(), is(equalTo(6L)));
|
||||||
|
assertThat(facet.getMax(), is(equalTo(2002.0)));
|
||||||
|
assertThat(facet.getMin(), is(equalTo(2000.0)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user