SOLR-10567: add support for DateRangeField in JSON facet range

This commit is contained in:
Munendra S N 2020-02-04 21:26:40 +05:30
parent b0bb299dc4
commit 4eff9c9b5e
4 changed files with 71 additions and 1 deletions

View File

@ -207,6 +207,8 @@ Improvements
* SOLR-14221: Upgrade restlet to version 2.4.0 (janhoy)
* SOLR-10567: Add Support for DateRangeField in JSON Facet range (Stephen Weiss, Munendra S N)
Optimizations
---------------------

View File

@ -32,6 +32,7 @@ import org.apache.solr.common.params.FacetParams.FacetRangeOther;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.schema.CurrencyFieldType;
import org.apache.solr.schema.CurrencyValue;
import org.apache.solr.schema.DateRangeField;
import org.apache.solr.schema.ExchangeRateProvider;
import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.SchemaField;
@ -249,6 +250,8 @@ class FacetRangeProcessor extends FacetProcessor<FacetRange> {
}
} else if (ft instanceof CurrencyFieldType) {
return new CurrencyCalc(sf);
} else if (ft instanceof DateRangeField) {
return new DateCalc(sf, null);
}
// if we made it this far, we have no idea what it is...
@ -737,6 +740,7 @@ class FacetRangeProcessor extends FacetProcessor<FacetRange> {
return ((Number) value).floatValue() + Float.parseFloat(gap);
}
}
private static class DoubleCalc extends Calc {
@Override
public Comparable bitsToValue(long bits) {
@ -762,6 +766,7 @@ class FacetRangeProcessor extends FacetProcessor<FacetRange> {
return ((Number) value).doubleValue() + Double.parseDouble(gap);
}
}
private static class IntCalc extends Calc {
public IntCalc(final SchemaField f) { super(f); }
@ -778,6 +783,7 @@ class FacetRangeProcessor extends FacetProcessor<FacetRange> {
return ((Number) value).intValue() + Integer.parseInt(gap);
}
}
private static class LongCalc extends Calc {
public LongCalc(final SchemaField f) { super(f); }
@ -790,13 +796,15 @@ class FacetRangeProcessor extends FacetProcessor<FacetRange> {
return ((Number) value).longValue() + Long.parseLong(gap);
}
}
private static class DateCalc extends Calc {
private final Date now;
public DateCalc(final SchemaField f,
final Date now) {
super(f);
this.now = now;
if (! (field.getType() instanceof TrieDateField) && !(field.getType().isPointField()) ) {
if (!(field.getType() instanceof TrieDateField || field.getType().isPointField() ||
field.getType() instanceof DateRangeField)) {
throw new IllegalArgumentException("SchemaField must use field type extending TrieDateField, DateRangeField or PointField");
}
}

View File

@ -226,6 +226,9 @@
<dynamicField name="*_dtd" type="date" indexed="true" stored="false" docValues="true"/>
<dynamicField name="*_dtds" type="date" indexed="true" stored="false" multiValued="true" docValues="true"/>
<dynamicField name="*_drf" type="dateRange" indexed="true" stored="true"/>
<dynamicField name="*_drfs" type="dateRange" indexed="true" multiValued="true" stored="true"/>
<!-- docvalues and stored (S suffix) -->
<dynamicField name="*_idS" type="int" indexed="true" stored="true" docValues="true"/>
<dynamicField name="*_idsS" type="int" indexed="true" stored="true" multiValued="true" docValues="true"/>
@ -437,6 +440,7 @@
<!-- A Trie based date field for faster date range queries and date faceting. -->
<fieldType name="tdate" class="${solr.tests.DateFieldType}" precisionStep="6" positionIncrementGap="0"/>
<fieldType name="dateRange" class="solr.DateRangeField"/>
<!--Binary data type. The data should be sent/retrieved in as Base64 encoded Strings -->
<fieldtype name="binary" class="solr.BinaryField"/>

View File

@ -3463,6 +3463,62 @@ public class TestJsonFacets extends SolrTestCaseHS {
"facets=={count:6, price:{buckets:[{val:\"[*,*]\",count:5}]}}");
}
@Test
public void testDateFacets() throws Exception {
Client client = Client.localClient();
client.deleteByQuery("*:*", null);
boolean multiValue = random().nextBoolean();
String dateField = multiValue? "b_dts": "b_dt";
String dateRange = multiValue? "b_drfs": "b_drf";
client.add(sdoc("id", "1", "cat_s", "A", dateField, "2014-03-15T12:00:00Z",
dateRange, "2014-03-15T12:00:00Z"), null);
client.add(sdoc("id", "2", "cat_s", "B", dateField, "2015-01-03T00:00:00Z",
dateRange, "2015-01-03T00:00:00Z"), null);
client.add(sdoc("id", "3"), null);
client.commit();
client.add(sdoc("id", "4", "cat_s", "A", dateField, "2014-03-15T12:00:00Z",
dateRange, "2014-03-15T12:00:00Z"), null);
client.add(sdoc("id", "5", "cat_s", "B", dateField, "2015-01-03T00:00:00Z",
dateRange, "2015-01-03T00:00:00Z"),null);
client.commit();
client.add(sdoc("id", "6", "cat_s", "B", dateField, "2014-03-15T12:00:00Z",
dateRange, "2014-03-15T12:00:00Z"),null);
client.commit();
SolrParams p = params("q", "*:*", "rows", "0");
for (String s : new String[]{dateField, dateRange}) {
client.testJQ(params(p, "json.facet"
, "{date:{type : range, mincount:1, field :" + s +
",start:'2013-11-01T00:00:00Z',end:NOW,gap:'+90DAY'}}"),
"facets=={count:6, date:{buckets:" +
"[{val:\"2014-01-30T00:00:00Z\",count:3}, {val:\"2014-10-27T00:00:00Z\",count:2}]" +
"}}");
// with ranges
client.testJQ(params(p, "json.facet"
, "{date:{type : range, mincount:1, field :" + s +
",ranges:[{from:'2013-11-01T00:00:00Z', to:'2014-04-30T00:00:00Z'}," +
"{from:'2015-01-01T00:00:00Z', to:'2020-01-30T00:00:00Z'}]}}"),
"facets=={count:6, date:{buckets:" +
"[{val:\"[2013-11-01T00:00:00Z,2014-04-30T00:00:00Z)\",count:3}," +
" {val:\"[2015-01-01T00:00:00Z,2020-01-30T00:00:00Z)\",count:2}]" +
"}}");
}
client.add(sdoc("id", "7", "cat_s", "B", dateRange, "[2010 TO 2014-05-21]"),null);
client.commit();
client.testJQ(params(p, "json.facet"
, "{date:{type : range, other:'before', field :" + dateRange +
",start:'2011-11-01T00:00:00Z',end:'2016-01-30T00:00:00Z',gap:'+1YEAR'}}"),
"facets=={count:7, date:{buckets:[" +
"{val:\"2011-11-01T00:00:00Z\",count:1}, {val:\"2012-11-01T00:00:00Z\",count:1}," +
"{val:\"2013-11-01T00:00:00Z\",count:4}, {val:\"2014-11-01T00:00:00Z\",count:2}," +
"{val:\"2015-11-01T00:00:00Z\",count:0}" +
"],before:{count:1}" +
"}}");
}
@Test
public void testRangeFacetWithRangesInNewFormat() throws Exception {
Client client = Client.localClient();