diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 33490d62ab7..b430eb645f4 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -363,6 +363,9 @@ Bug Fixes * SOLR-2763: Extracting update request handler throws exception and returns 400 when zero-length file posted using multipart form post (janhoy) +* SOLR-2780: Fixed issue where multi select facets didn't respect group.truncate parameter. + (Martijn van Groningen, Ramzi Alqrainy) + 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 d6cedaaada3..a99767b477a 100644 --- a/solr/core/src/java/org/apache/solr/request/SimpleFacets.java +++ b/solr/core/src/java/org/apache/solr/request/SimpleFacets.java @@ -18,11 +18,14 @@ package org.apache.solr.request; import org.apache.lucene.index.*; +import org.apache.lucene.queries.function.FunctionQuery; +import org.apache.lucene.queries.function.ValueSource; +import org.apache.lucene.queries.function.valuesource.QueryValueSource; import org.apache.lucene.queryparser.classic.ParseException; import org.apache.lucene.search.*; -import org.apache.lucene.util.BytesRef; -import org.apache.lucene.util.CharsRef; -import org.apache.lucene.util.UnicodeUtil; +import org.apache.lucene.search.grouping.AbstractAllGroupHeadsCollector; +import org.apache.lucene.search.grouping.TermAllGroupHeadsCollector; +import org.apache.lucene.util.*; import org.apache.lucene.util.packed.Direct16; import org.apache.lucene.util.packed.Direct32; import org.apache.lucene.util.packed.Direct8; @@ -162,7 +165,26 @@ public class SimpleFacets { } // get the new base docset for this facet - base = searcher.getDocSet(qlist); + DocSet base = searcher.getDocSet(qlist); + if (rb.grouping() && rb.getGroupingSpec().isTruncateGroups()) { + Grouping grouping = new Grouping(searcher, null, rb.getQueryCommand(), false, 0, false); + if (rb.getGroupingSpec().getFields().length > 0) { + grouping.addFieldCommand(rb.getGroupingSpec().getFields()[0], req); + } else if (rb.getGroupingSpec().getFunctions().length > 0) { + grouping.addFunctionCommand(rb.getGroupingSpec().getFunctions()[0], req); + } else { + this.base = base; + return; + } + AbstractAllGroupHeadsCollector allGroupHeadsCollector = grouping.getCommands().get(0).createAllGroupCollector(); + searcher.search(new MatchAllDocsQuery(), base.getTopFilter(), allGroupHeadsCollector); + int maxDoc = searcher.maxDoc(); + FixedBitSet fixedBitSet = allGroupHeadsCollector.retrieveGroupHeads(maxDoc); + long[] bits = fixedBitSet.getBits(); + this.base = new BitDocSet(new OpenBitSet(bits, bits.length)); + } else { + this.base = base; + } } } diff --git a/solr/core/src/test/org/apache/solr/TestGroupingSearch.java b/solr/core/src/test/org/apache/solr/TestGroupingSearch.java index ea3451b91eb..0951e36a239 100644 --- a/solr/core/src/test/org/apache/solr/TestGroupingSearch.java +++ b/solr/core/src/test/org/apache/solr/TestGroupingSearch.java @@ -279,6 +279,33 @@ public class TestGroupingSearch extends SolrTestCaseJ4 { "/grouped=={'value4_i':{'matches':5,'groups':[{'groupValue':1,'doclist':{'numFound':3,'start':0,'docs':[{'id':'1'}]}}]}}", "/facet_counts=={'facet_queries':{},'facet_fields':{'value3_s1':['a',1,'b',1]},'facet_dates':{},'facet_ranges':{}}" ); + + // Multi select facets AND group.truncate=true + req = req("q", "*:*", "rows", "1", "group", "true", "group.field", "value4_i", "fl", "id", "facet", "true", + "facet.field", "{!ex=v}value3_s1", "group.truncate", "true", "fq", "{!tag=v}value3_s1:b"); + assertJQ( + req, + "/grouped=={'value4_i':{'matches':2,'groups':[{'groupValue':2,'doclist':{'numFound':2,'start':0,'docs':[{'id':'3'}]}}]}}", + "/facet_counts=={'facet_queries':{},'facet_fields':{'value3_s1':['a',1,'b',1]},'facet_dates':{},'facet_ranges':{}}" + ); + + // Multi select facets AND group.truncate=false + req = req("q", "*:*", "rows", "1", "group", "true", "group.field", "value4_i", "fl", "id", "facet", "true", + "facet.field", "{!ex=v}value3_s1", "group.truncate", "false", "fq", "{!tag=v}value3_s1:b"); + assertJQ( + req, + "/grouped=={'value4_i':{'matches':2,'groups':[{'groupValue':2,'doclist':{'numFound':2,'start':0,'docs':[{'id':'3'}]}}]}}", + "/facet_counts=={'facet_queries':{},'facet_fields':{'value3_s1':['a',3,'b',2]},'facet_dates':{},'facet_ranges':{}}" + ); + + // Multi select facets AND group.truncate=true + req = req("q", "*:*", "rows", "1", "group", "true", "group.func", "sub(value4_i,1)", "fl", "id", "facet", "true", + "facet.field", "{!ex=v}value3_s1", "group.truncate", "true", "fq", "{!tag=v}value3_s1:b"); + assertJQ( + req, + "/grouped=={'sub(value4_i,1)':{'matches':2,'groups':[{'groupValue':1.0,'doclist':{'numFound':2,'start':0,'docs':[{'id':'3'}]}}]}}", + "/facet_counts=={'facet_queries':{},'facet_fields':{'value3_s1':['a',1,'b',1]},'facet_dates':{},'facet_ranges':{}}" + ); } static String f = "foo_i";