diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 3f8f2e3b1f3..01b04aa37e7 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -592,6 +592,9 @@ Other Changes * SOLR-10847: Provide a clear exception when attempting to use the terms component with points fields. (hossman, Steve Rowe) + +* SOLR-10033: Provide a clear exception when attempting to facet with facet.mincount=0 over points fields. + (Steve Rowe) ================== 6.7.0 ================== diff --git a/solr/core/src/java/org/apache/solr/request/NumericFacets.java b/solr/core/src/java/org/apache/solr/request/NumericFacets.java index fd17f1f7397..f9f38b3dbaf 100644 --- a/solr/core/src/java/org/apache/solr/request/NumericFacets.java +++ b/solr/core/src/java/org/apache/solr/request/NumericFacets.java @@ -43,6 +43,7 @@ import org.apache.lucene.util.CharsRefBuilder; import org.apache.lucene.util.NumericUtils; import org.apache.lucene.util.PriorityQueue; import org.apache.lucene.util.StringHelper; +import org.apache.solr.common.SolrException; import org.apache.solr.common.params.FacetParams; import org.apache.solr.common.util.NamedList; import org.apache.solr.schema.FieldType; @@ -178,6 +179,11 @@ final class NumericFacets { if (numericType == null) { throw new IllegalStateException(); } + if (zeros && ft.isPointField()) { + throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, + "Cannot use " + FacetParams.FACET_MINCOUNT + "=0 on field " + sf.getName() + " which is Points-based"); + } + zeros = zeros && !ft.isPointField() && sf.indexed(); // We don't return zeros when using PointFields or when index=false final List leaves = searcher.getIndexReader().leaves(); @@ -407,11 +413,18 @@ final class NumericFacets { private static NamedList getCountsMultiValued(SolrIndexSearcher searcher, DocSet docs, String fieldName, int offset, int limit, int mincount, boolean missing, String sort) throws IOException { // If facet.mincount=0 with PointFields the only option is to get the values from DocValues - // not currently supported. See SOLR-10033 + // not currently supported. See SOLR-11174 + boolean zeros = mincount <= 0; mincount = Math.max(mincount, 1); final SchemaField sf = searcher.getSchema().getField(fieldName); final FieldType ft = sf.getType(); assert sf.multiValued(); + + if (zeros && ft.isPointField()) { + throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, + "Cannot use " + FacetParams.FACET_MINCOUNT + "=0 on field " + sf.getName() + " which is Points-based"); + } + final List leaves = searcher.getIndexReader().leaves(); // 1. accumulate diff --git a/solr/core/src/test/org/apache/solr/request/TestFaceting.java b/solr/core/src/test/org/apache/solr/request/TestFaceting.java index 9559b4ca405..1d99127d37e 100644 --- a/solr/core/src/test/org/apache/solr/request/TestFaceting.java +++ b/solr/core/src/test/org/apache/solr/request/TestFaceting.java @@ -27,6 +27,7 @@ import org.apache.lucene.index.Term; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.util.BytesRef; import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.common.SolrException; import org.apache.solr.common.params.FacetParams; import org.apache.solr.search.SolrIndexSearcher; import org.apache.solr.uninverting.DocTermOrds; @@ -335,7 +336,7 @@ public class TestFaceting extends SolrTestCaseJ4 { @Test public void testFacetSortWithMinCount0() { - assumeFalse("facet.mincount=0 doesn't work with point fields (SOLR-10033) or single valued DV", + assumeFalse("facet.mincount=0 doesn't work with point fields (SOLR-11174) or single valued DV", Boolean.getBoolean(NUMERIC_POINTS_SYSPROP) || Boolean.getBoolean(NUMERIC_DOCVALUES_SYSPROP)); assertU(adoc("id", "1", "f_td", "-420.126")); @@ -356,8 +357,31 @@ public class TestFaceting extends SolrTestCaseJ4 { "//lst[@name='facet_fields']/lst[@name='f_td']/int[3][@name='-1.218']"); } + @Test + public void testFacetOverPointFieldWithMinCount0() { + String field = "f_" + new String[]{"i","l","f","d"}[random().nextInt(4)] + "_p"; + final SolrQueryRequest req = req("q", "id:1.0", + FacetParams.FACET, "true", + FacetParams.FACET_FIELD, field, + FacetParams.FACET_MINCOUNT, "0", + FacetParams.FACET_METHOD, FacetParams.FACET_METHOD_fc); + Exception e = expectThrows(SolrException.class, () -> h.query(req)); + assertEquals(SolrException.ErrorCode.BAD_REQUEST.code, ((SolrException)e).code()); + assertTrue(e.getMessage().contains("Cannot use facet.mincount=0 on field " + field + " which is Points-based")); - public void testSimpleFacetCountsWithMultipleConfigurationsForSameField() { + String mvField = "f_" + new String[]{"is","ls","fs","ds"}[random().nextInt(4)] + "_p"; + final SolrQueryRequest req2 = req("q", "id:1.0", + FacetParams.FACET, "true", + FacetParams.FACET_FIELD, mvField, + FacetParams.FACET_MINCOUNT, "0", + FacetParams.FACET_METHOD, FacetParams.FACET_METHOD_fc); + e = expectThrows(SolrException.class, () -> h.query(req2)); + assertEquals(SolrException.ErrorCode.BAD_REQUEST.code, ((SolrException)e).code()); + assertTrue(e.getMessage().contains("Cannot use facet.mincount=0 on field " + mvField + " which is Points-based")); + } + + + public void testSimpleFacetCountsWithMultipleConfigurationsForSameField() { clearIndex(); String fname = "trait_ss"; assertU(adoc("id", "42",