Skip to content

Commit 35cb4e6

Browse files
committed
DATAES-21 statistical facets(Petar Tahchiev)
1 parent 99940f4 commit 35cb4e6

File tree

6 files changed

+187
-14
lines changed

6 files changed

+187
-14
lines changed

src/main/java/org/springframework/data/elasticsearch/core/facet/FacetMapper.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
package org.springframework.data.elasticsearch.core.facet;
22

33
import org.elasticsearch.search.facet.Facet;
4+
import org.elasticsearch.search.facet.histogram.HistogramFacet;
45
import org.elasticsearch.search.facet.range.RangeFacet;
6+
import org.elasticsearch.search.facet.statistical.StatisticalFacet;
57
import org.elasticsearch.search.facet.terms.TermsFacet;
6-
import org.springframework.data.elasticsearch.core.facet.result.Range;
7-
import org.springframework.data.elasticsearch.core.facet.result.RangeResult;
8-
import org.springframework.data.elasticsearch.core.facet.result.Term;
9-
import org.springframework.data.elasticsearch.core.facet.result.TermResult;
8+
import org.springframework.data.elasticsearch.core.facet.result.*;
109

1110
import java.util.ArrayList;
1211
import java.util.List;
1312

1413
/**
1514
* @author Artur Konczak
15+
* @author Petar Tahchiev
1616
*/
1717
public class FacetMapper {
1818

@@ -25,6 +25,10 @@ public static FacetResult parse(Facet facet) {
2525
return parseRange((RangeFacet) facet);
2626
}
2727

28+
if (facet instanceof StatisticalFacet) {
29+
return parseStatistical((StatisticalFacet) facet);
30+
}
31+
2832
return null;
2933
}
3034

@@ -44,4 +48,8 @@ private static FacetResult parseRange(RangeFacet facet) {
4448
return new RangeResult(facet.getName(), entries);
4549
}
4650

51+
private static FacetResult parseStatistical(StatisticalFacet facet) {
52+
return new StatisticalResult(facet.getName(), facet.getCount(), facet.getMax(), facet.getMin(), facet.getMean(), facet.getStdDeviation(), facet.getSumOfSquares(), facet.getTotal(), facet.getVariance());
53+
}
54+
4755
}
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package org.springframework.data.elasticsearch.core.facet;
22

3+
/**
4+
* @author Artur Konczak
5+
* @author Petar Tahchiev
6+
*/
37
public enum FacetType {
48

5-
term, range, histogram
9+
term, range, histogram, statistical
610

711
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package org.springframework.data.elasticsearch.core.facet.request;
2+
3+
import org.apache.commons.lang.ArrayUtils;
4+
import org.apache.commons.lang.StringUtils;
5+
import org.elasticsearch.search.facet.FacetBuilder;
6+
import org.elasticsearch.search.facet.FacetBuilders;
7+
import org.elasticsearch.search.facet.statistical.StatisticalFacetBuilder;
8+
import org.springframework.data.elasticsearch.core.facet.AbstractFacetRequest;
9+
import org.springframework.util.Assert;
10+
11+
/**
12+
* @author Petar Tahchiev
13+
*/
14+
public class StatisticalFacetRequest extends AbstractFacetRequest {
15+
16+
private String field;
17+
18+
private String[] fields;
19+
20+
public StatisticalFacetRequest(String name) {
21+
super(name);
22+
}
23+
24+
public void setField(String field) {
25+
this.field = field;
26+
}
27+
28+
public void setFields(String... fields) {
29+
this.fields = fields;
30+
}
31+
32+
public FacetBuilder getFacet() {
33+
Assert.notNull(getName(), "Facet name can't be a null !!!");
34+
Assert.isTrue(StringUtils.isNotBlank(field) && fields == null, "Please select field or fields on which to build the facets !!!");
35+
36+
StatisticalFacetBuilder builder = FacetBuilders.statisticalFacet(getName());
37+
if (ArrayUtils.isNotEmpty(fields)) {
38+
builder.fields(fields);
39+
} else {
40+
builder.field(field);
41+
}
42+
43+
return builder;
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package org.springframework.data.elasticsearch.core.facet.request;
2+
3+
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
4+
5+
/**
6+
* @author Petar Tahchiev
7+
*/
8+
public class StatisticalFacetRequestBuilder {
9+
10+
StatisticalFacetRequest result;
11+
12+
public StatisticalFacetRequestBuilder(String name) {
13+
result = new StatisticalFacetRequest(name);
14+
}
15+
16+
public StatisticalFacetRequestBuilder field(String field) {
17+
result.setField(field);
18+
return this;
19+
}
20+
21+
public StatisticalFacetRequestBuilder fields(String... fields) {
22+
result.setFields(fields);
23+
return this;
24+
}
25+
26+
public StatisticalFacetRequestBuilder applyQueryFilter() {
27+
result.setApplyQueryFilter(true);
28+
return this;
29+
}
30+
31+
public FacetRequest build() {
32+
return result;
33+
}
34+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package org.springframework.data.elasticsearch.core.facet.result;
2+
3+
import org.springframework.data.elasticsearch.core.facet.AbstactFacetResult;
4+
import org.springframework.data.elasticsearch.core.facet.FacetType;
5+
6+
/**
7+
* @author Petar Tahchiev
8+
*/
9+
public class StatisticalResult extends AbstactFacetResult {
10+
11+
private long count;
12+
13+
private double max;
14+
15+
private double min;
16+
17+
private double mean;
18+
19+
private double stdDeviation;
20+
21+
private double sumOfSquares;
22+
23+
private double total;
24+
25+
private double variance;
26+
27+
public StatisticalResult(String name, long count, double max, double min, double mean, double stdDeviation, double sumOfSquares, double total, double variance) {
28+
super(name, FacetType.statistical);
29+
this.count = count;
30+
this.max = max;
31+
this.min = min;
32+
this.mean = mean;
33+
this.stdDeviation = stdDeviation;
34+
this.sumOfSquares = sumOfSquares;
35+
this.total = total;
36+
this.variance = variance;
37+
}
38+
39+
public long getCount() {
40+
return count;
41+
}
42+
43+
public double getMax() {
44+
return max;
45+
}
46+
47+
public double getMin() {
48+
return min;
49+
}
50+
51+
public double getMean() {
52+
return mean;
53+
}
54+
55+
public double getStdDeviation() {
56+
return stdDeviation;
57+
}
58+
59+
public double getSumOfSquares() {
60+
return sumOfSquares;
61+
}
62+
63+
public double getTotal() {
64+
return total;
65+
}
66+
67+
public double getVariance() {
68+
return variance;
69+
}
70+
}

src/test/java/org/springframework/data/elasticsearch/core/facet/ElasticsearchTemplateFacetTests.java

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,8 @@
2323
import org.springframework.beans.factory.annotation.Autowired;
2424
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
2525
import org.springframework.data.elasticsearch.core.FacetedPage;
26-
import org.springframework.data.elasticsearch.core.facet.request.NativeFacetRequest;
27-
import org.springframework.data.elasticsearch.core.facet.request.RangeFacetRequestBuilder;
28-
import org.springframework.data.elasticsearch.core.facet.request.TermFacetRequestBuilder;
29-
import org.springframework.data.elasticsearch.core.facet.result.Range;
30-
import org.springframework.data.elasticsearch.core.facet.result.RangeResult;
31-
import org.springframework.data.elasticsearch.core.facet.result.Term;
32-
import org.springframework.data.elasticsearch.core.facet.result.TermResult;
26+
import org.springframework.data.elasticsearch.core.facet.request.*;
27+
import org.springframework.data.elasticsearch.core.facet.result.*;
3328
import org.springframework.data.elasticsearch.core.query.IndexQuery;
3429
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
3530
import org.springframework.data.elasticsearch.core.query.SearchQuery;
@@ -57,6 +52,7 @@ public class ElasticsearchTemplateFacetTests {
5752
public static final int YEAR_2002 = 2002;
5853
public static final int YEAR_2001 = 2001;
5954
public static final int YEAR_2000 = 2000;
55+
public static final String PUBLISHED_YEARS = "publishedYears";
6056
@Autowired
6157
private ElasticsearchTemplate elasticsearchTemplate;
6258

@@ -419,7 +415,7 @@ public void shouldReturnRangeFacetForGivenQuery() {
419415
String facetName = "rangeYears";
420416
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
421417
.withFacet(
422-
new RangeFacetRequestBuilder(facetName).field("publishedYears")
418+
new RangeFacetRequestBuilder(facetName).field(PUBLISHED_YEARS)
423419
.to(YEAR_2000).range(YEAR_2000, YEAR_2002).from(YEAR_2002).build()
424420
).build();
425421
// when
@@ -456,7 +452,7 @@ public void shouldReturnKeyValueRangeFacetForGivenQuery() {
456452
String facetName = "rangeScoreOverYears";
457453
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
458454
.withFacet(
459-
new RangeFacetRequestBuilder(facetName).fields("publishedYears", "score")
455+
new RangeFacetRequestBuilder(facetName).fields(PUBLISHED_YEARS, "score")
460456
.to(YEAR_2000).range(YEAR_2000, YEAR_2002).from(YEAR_2002).build()
461457
).build();
462458
// when
@@ -487,5 +483,21 @@ public void shouldReturnKeyValueRangeFacetForGivenQuery() {
487483
assertThat(range.getTotal(), is(40.0));
488484
}
489485

486+
@Test
487+
public void shouldReturnStatisticalFacetForGivenQuery() {
488+
// given
489+
String facetName = "statPublishedYear";
490+
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
491+
.withFacet(new StatisticalFacetRequestBuilder(facetName).field(PUBLISHED_YEARS).build()
492+
).build();
493+
// when
494+
FacetedPage<ArticleEntity> result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class);
495+
// then
496+
assertThat(result.getNumberOfElements(), is(equalTo(4)));
490497

498+
StatisticalResult facet = (StatisticalResult) result.getFacet(facetName);
499+
assertThat(facet.getCount(), is(equalTo(6L)));
500+
assertThat(facet.getMax(), is(equalTo(2002.0)));
501+
assertThat(facet.getMin(), is(equalTo(2000.0)));
502+
}
491503
}

0 commit comments

Comments
 (0)