From f9e3554838f3a43742928d11a7dcd9a8409e0c97 Mon Sep 17 00:00:00 2001 From: Dennis Gove Date: Wed, 4 Jan 2017 22:25:29 -0500 Subject: [PATCH] SOLR-7495: Support Facet.field on a non-DocValued, single-value, int field --- solr/CHANGES.txt | 2 + .../org/apache/solr/request/SimpleFacets.java | 37 +++++++++++-------- .../apache/solr/request/SimpleFacetsTest.java | 12 ++++-- 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 556ab23a0d1..e3a4b4b5d01 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -327,6 +327,8 @@ Bug Fixes * SOLR-9919: random Streaming Expression is not registered in /stream or /graph handler (Joel Bernstein) +* SOLR-7495: Support Facet.field on a non-DocValued, single-value, int field (Varun Thacker, Scott Stults) + Other Changes ---------------------- diff --git a/solr/core/src/java/org/apache/solr/request/SimpleFacets.java b/solr/core/src/java/org/apache/solr/request/SimpleFacets.java index 93ca4fa906e..f29a7676a33 100644 --- a/solr/core/src/java/org/apache/solr/request/SimpleFacets.java +++ b/solr/core/src/java/org/apache/solr/request/SimpleFacets.java @@ -45,6 +45,7 @@ import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.Collector; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.FilterCollector; import org.apache.lucene.search.LeafCollector; @@ -649,21 +650,10 @@ public class SimpleFacets { BytesRef prefixBytesRef = prefix != null ? new BytesRef(prefix) : null; final TermGroupFacetCollector collector = TermGroupFacetCollector.createTermGroupFacetCollector(groupField, field, multiToken, prefixBytesRef, 128); - SchemaField sf = searcher.getSchema().getFieldOrNull(groupField); - - if (sf != null && sf.hasDocValues() == false && sf.multiValued() == false && sf.getType().getNumericType() != null) { - // it's a single-valued numeric field: we must currently create insanity :( - // there isn't a GroupedFacetCollector that works on numerics right now... - searcher.search(base.getTopFilter(), new FilterCollector(collector) { - @Override - public LeafCollector getLeafCollector(LeafReaderContext context) throws IOException { - LeafReader insane = Insanity.wrapInsanity(context.reader(), groupField); - return in.getLeafCollector(insane.getContext()); - } - }); - } else { - searcher.search(base.getTopFilter(), collector); - } + Collector groupWrapper = getInsanityWrapper(groupField, collector); + Collector fieldWrapper = getInsanityWrapper(field, groupWrapper); + // When GroupedFacetCollector can handle numerics we can remove the wrapped collectors + searcher.search(base.getTopFilter(), fieldWrapper); boolean orderByCount = sort.equals(FacetParams.FACET_SORT_COUNT) || sort.equals(FacetParams.FACET_SORT_COUNT_LEGACY); TermGroupFacetCollector.GroupedFacetResult result @@ -691,6 +681,23 @@ public class SimpleFacets { return facetCounts; } + + private Collector getInsanityWrapper(final String field, Collector collector) { + SchemaField sf = searcher.getSchema().getFieldOrNull(field); + if (sf != null && !sf.hasDocValues() && !sf.multiValued() && sf.getType().getNumericType() != null) { + // it's a single-valued numeric field: we must currently create insanity :( + // there isn't a GroupedFacetCollector that works on numerics right now... + return new FilterCollector(collector) { + @Override + public LeafCollector getLeafCollector(LeafReaderContext context) throws IOException { + LeafReader insane = Insanity.wrapInsanity(context.reader(), field); + return in.getLeafCollector(insane.getContext()); + } + }; + } else { + return collector; + } + } static final Executor directExecutor = new Executor() { diff --git a/solr/core/src/test/org/apache/solr/request/SimpleFacetsTest.java b/solr/core/src/test/org/apache/solr/request/SimpleFacetsTest.java index 85035b9c88a..a21135e113c 100644 --- a/solr/core/src/test/org/apache/solr/request/SimpleFacetsTest.java +++ b/solr/core/src/test/org/apache/solr/request/SimpleFacetsTest.java @@ -384,7 +384,7 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 { "*[count(//doc)=5]" ); assertQ( - "Return two facet counts for field airport_a", + "Return two facet counts for field airport_a and duration_i1", req( "q", "*:*", "fq", "id:[2000 TO 2004]", @@ -393,12 +393,18 @@ public class SimpleFacetsTest extends SolrTestCaseJ4 { "group.field", "hotel_s1", "facet", "true", "facet.limit", facetLimit, - "facet.field", "airport_s1" + "facet.field", "airport_s1", + "facet.field", "duration_i1" ), "//lst[@name='facet_fields']/lst[@name='airport_s1']", "*[count(//lst[@name='airport_s1']/int)=2]", "//lst[@name='airport_s1']/int[@name='ams'][.='2']", - "//lst[@name='airport_s1']/int[@name='dus'][.='1']" + "//lst[@name='airport_s1']/int[@name='dus'][.='1']", + + "//lst[@name='facet_fields']/lst[@name='duration_i1']", + "*[count(//lst[@name='duration_i1']/int)=2]", + "//lst[@name='duration_i1']/int[@name='5'][.='2']", + "//lst[@name='duration_i1']/int[@name='10'][.='2']" ); assertQ( "Return one facet count for field airport_a using facet.offset",