From cc344dc6bd9e71ed7848618630b51f4633e1dd50 Mon Sep 17 00:00:00 2001 From: yonik Date: Tue, 5 Sep 2017 16:06:41 -0400 Subject: [PATCH] SOLR-11316: date support for min/max, fix missing bug for int/long fields --- solr/CHANGES.txt | 3 ++ .../apache/solr/search/facet/MinMaxAgg.java | 31 +++++++++++++++++-- .../solr/search/facet/TestJsonFacets.java | 22 +++++++++++-- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index ad0a522c642..be89fb1880f 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -86,6 +86,9 @@ New Features * SOLR-11317: JSON Facet API: min/max aggregations on numeric fields are now typed better so int/long fields return an appropriate integral type rather than a double. (yonik) +* SOLR-11316: JSON Facet API: min/max aggregations are now supported on single-valued date fields. + (yonik) + Bug Fixes ---------------------- diff --git a/solr/core/src/java/org/apache/solr/search/facet/MinMaxAgg.java b/solr/core/src/java/org/apache/solr/search/facet/MinMaxAgg.java index 5a48ab2221c..008d0fd4445 100644 --- a/solr/core/src/java/org/apache/solr/search/facet/MinMaxAgg.java +++ b/solr/core/src/java/org/apache/solr/search/facet/MinMaxAgg.java @@ -18,6 +18,7 @@ package org.apache.solr.search.facet; import java.io.IOException; import java.util.Arrays; +import java.util.Date; import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.MultiDocValues; @@ -70,8 +71,9 @@ public class MinMaxAgg extends SimpleAggValueSource { return new DFuncAcc(vs, fcontext, numSlots); case INTEGER: case LONG: - case DATE: return new LFuncAcc(vs, fcontext, numSlots); + case DATE: + return new DateFuncAcc(vs, fcontext, numSlots); } } @@ -185,7 +187,7 @@ public class MinMaxAgg extends SimpleAggValueSource { @Override public Object getValue(int slot) { long val = result[slot]; - if (val == 0 && exists.get(slot)) { + if (val == 0 && !exists.get(slot)) { return null; } else { return val; @@ -221,6 +223,31 @@ public class MinMaxAgg extends SimpleAggValueSource { } + class DateFuncAcc extends LongFuncSlotAcc { + private static final long MISSING = Long.MIN_VALUE; + public DateFuncAcc(ValueSource values, FacetContext fcontext, int numSlots) { + super(values, fcontext, numSlots, MISSING); + } + + @Override + public void collect(int doc, int slotNum) throws IOException { + long val = values.longVal(doc); + if (val == 0 && !values.exists(doc)) return; // depend on fact that non existing values return 0 for func query + + long currVal = result[slotNum]; + if (Long.compare(val, currVal) * minmax < 0 || currVal == MISSING) { + result[slotNum] = val; + } + } + + // let compare be the default for now (since we can't yet correctly handle sortMissingLast + + @Override + public Object getValue(int slot) { + return result[slot] == MISSING ? null : new Date(result[slot]); + } + } + abstract class OrdAcc extends SlotAcc { final static int MISSING = -1; diff --git a/solr/core/src/test/org/apache/solr/search/facet/TestJsonFacets.java b/solr/core/src/test/org/apache/solr/search/facet/TestJsonFacets.java index 559240bc048..33d7fa89c78 100644 --- a/solr/core/src/test/org/apache/solr/search/facet/TestJsonFacets.java +++ b/solr/core/src/test/org/apache/solr/search/facet/TestJsonFacets.java @@ -695,11 +695,29 @@ public class TestJsonFacets extends SolrTestCaseHS { "}" ) , "facets=={count:6 " + - ",f1:{ buckets:[{val:-1,count:2,a:-5},{val:3,count:2,a:-5},{val:-5,count:1,a:2},{val:2,count:1,a:2},{val:0,count:2,a:3}, ] } " + - ",f2:{ buckets:[{val:0,count:2,a:7},{val:3,count:2,a:3},{val:-5,count:1,a:2},{val:2,count:1,a:2},{val:-1,count:2,a:-5}, ] } " + + ",f1:{ buckets:[{val:-1,count:2,a:-5},{val:3,count:2,a:-5},{val:-5,count:1,a:2},{val:2,count:1,a:2},{val:0,count:2,a:3} ] } " + + ",f2:{ buckets:[{val:0,count:2,a:7},{val:3,count:2,a:3},{val:-5,count:1,a:2},{val:2,count:1,a:2},{val:-1,count:2,a:-5} ] } " + "}" ); + + // Same thing for dates + // test min/max of string field + if (date.equals("date_dt") || date.equals("date_dtd")) { // supports only single valued currently... + client.testJQ(params(p, "q", "*:*" + , "json.facet", "{" + + " f3:{${terms} type:field, field:${num_is}, facet:{a:'min(${date})'}, sort:'a desc' }" + + ",f4:{${terms} type:field, field:${num_is}, facet:{a:'max(${date})'}, sort:'a asc' }" + + "}" + ) + , "facets=={count:6 " + + ",f3:{ buckets:[{val:-1,count:2,a:'2002-02-02T02:02:02Z'},{val:3,count:2,a:'2002-02-02T02:02:02Z'},{val:0,count:2,a:'2001-02-03T01:02:03Z'},{val:-5,count:1,a:'2001-01-01T01:01:01Z'},{val:2,count:1,a:'2001-01-01T01:01:01Z'} ] } " + + ",f4:{ buckets:[{val:-5,count:1,a:'2001-01-01T01:01:01Z'},{val:2,count:1,a:'2001-01-01T01:01:01Z'},{val:-1,count:2,a:'2002-03-01T03:02:01Z'},{val:0,count:2,a:'2003-03-03T03:03:03Z'},{val:3,count:2,a:'2003-03-03T03:03:03Z'} ] } " + + "}" + ); + } + + // percentiles 0,10,50,90,100 // catA: 2.0 2.2 3.0 3.8 4.0 // catB: -9.0 -8.2 -5.0 7.800000000000001 11.0