diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/RangeFacetRequest.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/request/RangeFacetRequest.java index 511aa9029..e2be47092 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/RangeFacetRequest.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/facet/request/RangeFacetRequest.java @@ -29,6 +29,7 @@ import org.springframework.util.Assert; * Range facet for numeric fields * * @author Artur Konczak + * @author Akos Bordas */ public class RangeFacetRequest extends AbstractFacetRequest { @@ -36,8 +37,7 @@ public class RangeFacetRequest extends AbstractFacetRequest { private String keyField; private String valueField; - private List from = new ArrayList(); - private List to = new ArrayList(); + private List entries = new ArrayList(); public RangeFacetRequest(String name) { super(name); @@ -53,17 +53,19 @@ public class RangeFacetRequest extends AbstractFacetRequest { } public void range(Double from, Double to) { - if (from == null) { - this.from.add(Double.NEGATIVE_INFINITY); - } else { - this.from.add(from); - } + entries.add(new DoubleEntry(from, to)); + } - if (to == null) { - this.to.add(Double.POSITIVE_INFINITY); - } else { - this.to.add(to); - } + public void range(String from, String to) { + entries.add(new StringEntry(from, to)); + } + + public void addRange(Double from, Double to) { + entries.add(new DoubleEntry(from, to)); + } + + public void addRange(String from, String to) { + entries.add(new StringEntry(from, to)); } @Override @@ -77,11 +79,54 @@ public class RangeFacetRequest extends AbstractFacetRequest { } else { builder.field(field); } - Assert.notEmpty(from, "Please select at last one range"); - Assert.notEmpty(to, "Please select at last one range"); - for (int i = 0; i < from.size(); i++) { - builder.addRange(from.get(i), to.get(i)); + + for (Entry entry : entries) { + if (entry instanceof DoubleEntry) { + DoubleEntry doubleEntry = (DoubleEntry) entry; + builder.addRange(validateValue(doubleEntry.getFrom(), Double.NEGATIVE_INFINITY), validateValue(doubleEntry.getTo(), Double.POSITIVE_INFINITY)); + } else { + StringEntry stringEntry = (StringEntry) entry; + builder.addRange(stringEntry.getFrom(), stringEntry.getTo()); + } } + return builder; } + + private double validateValue(Double value, double defaultValue) { + return value == null ? defaultValue : value; + } + + static class DoubleEntry extends Entry { + + DoubleEntry(Double from, Double to) { + super(from, to); + } + } + + static class StringEntry extends Entry { + + StringEntry(String from, String to) { + super(from, to); + } + } + + static class Entry { + + T from; + T to; + + Entry(T from, T to) { + this.from = from; + this.to = to; + } + + public T getFrom() { + return from; + } + + public T getTo() { + return to; + } + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/RangeFacetRequestBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/request/RangeFacetRequestBuilder.java index 30ad3e11a..9a95bf0ac 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/RangeFacetRequestBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/facet/request/RangeFacetRequestBuilder.java @@ -46,6 +46,11 @@ public class RangeFacetRequestBuilder { return this; } + public RangeFacetRequestBuilder range(String from, String to) { + result.range(from, to); + return this; + } + public RangeFacetRequestBuilder from(double from) { result.range(from, null); return this; @@ -56,6 +61,16 @@ public class RangeFacetRequestBuilder { return this; } + public RangeFacetRequestBuilder from(String from) { + result.range(from, null); + return this; + } + + public RangeFacetRequestBuilder to(String to) { + result.range(null, to); + return this; + } + public RangeFacetRequestBuilder applyQueryFilter() { result.setApplyQueryFilter(true); return this; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/facet/ElasticsearchTemplateFacetTests.java b/src/test/java/org/springframework/data/elasticsearch/core/facet/ElasticsearchTemplateFacetTests.java index b7432c93e..d127facde 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/facet/ElasticsearchTemplateFacetTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/facet/ElasticsearchTemplateFacetTests.java @@ -473,6 +473,42 @@ public class ElasticsearchTemplateFacetTests { assertThat(range.getTotal(), is(40.0)); } + @Test + public void shouldReturnKeyValueRangeFacetForStringValuesInGivenQuery() { + // given + String facetName = "rangeScoreOverYears"; + SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + .withFacet( + new RangeFacetRequestBuilder(facetName).fields(PUBLISHED_YEARS, "score") + .to("2000").range("2000", "2002").from("2002").build() + ).build(); + // when + FacetedPage result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class); + // then + assertThat(result.getNumberOfElements(), is(equalTo(4))); + + RangeResult facet = (RangeResult) result.getFacet(facetName); + assertThat(facet.getRanges().size(), is(equalTo(3))); + + Range range = facet.getRanges().get(0); + assertThat(range.getFrom(), nullValue()); + assertThat(range.getTo(), is((double) YEAR_2000)); + assertThat(range.getCount(), is(0L)); + assertThat(range.getTotal(), is(0.0)); + + range = facet.getRanges().get(1); + assertThat(range.getFrom(), is((double) YEAR_2000)); + assertThat(range.getTo(), is((double) YEAR_2002)); + assertThat(range.getCount(), is(3L)); + assertThat(range.getTotal(), is(90.0)); + + range = facet.getRanges().get(2); + assertThat(range.getFrom(), is((double) YEAR_2002)); + assertThat(range.getTo(), nullValue()); + assertThat(range.getCount(), is(1L)); + assertThat(range.getTotal(), is(40.0)); + } + @Test public void shouldReturnStatisticalFacetForGivenQuery() { // given