You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ds...@apache.org on 2015/02/10 04:23:19 UTC
svn commit: r1658617 - in /lucene/dev/branches/branch_5x: ./ solr/
solr/core/ solr/core/src/java/org/apache/solr/handler/component/
solr/core/src/java/org/apache/solr/request/
solr/core/src/java/org/apache/solr/util/
solr/core/src/test/org/apache/solr/...
Author: dsmiley
Date: Tue Feb 10 03:23:18 2015
New Revision: 1658617
URL: http://svn.apache.org/r1658617
Log:
SOLR-7005: New facet.heatmap on spatial RPT fields
Added:
lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/component/SpatialHeatmapFacets.java
- copied, changed from r1658614, lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/SpatialHeatmapFacets.java
lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/handler/component/SpatialHeatmapFacetsTest.java
- copied unchanged from r1658614, lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/component/SpatialHeatmapFacetsTest.java
Modified:
lucene/dev/branches/branch_5x/ (props changed)
lucene/dev/branches/branch_5x/solr/ (props changed)
lucene/dev/branches/branch_5x/solr/CHANGES.txt (contents, props changed)
lucene/dev/branches/branch_5x/solr/core/ (props changed)
lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/component/FacetComponent.java
lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/request/SimpleFacets.java
lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/util/SpatialUtils.java
lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/TestGroupingSearch.java
lucene/dev/branches/branch_5x/solr/solrj/ (props changed)
lucene/dev/branches/branch_5x/solr/solrj/src/java/org/apache/solr/common/params/FacetParams.java
Modified: lucene/dev/branches/branch_5x/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/CHANGES.txt?rev=1658617&r1=1658616&r2=1658617&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/CHANGES.txt (original)
+++ lucene/dev/branches/branch_5x/solr/CHANGES.txt Tue Feb 10 03:23:18 2015
@@ -53,10 +53,13 @@ New Features
for setting 'highlight' and 'allTermsRequired' in the suggester configuration.
(Boon Low, Varun Thacker via Tomás Fernández Löbbe)
-* SOLR-7083:Support managing all named components in solrconfig such as
+* SOLR-7083: Support managing all named components in solrconfig such as
requestHandler, queryParser, queryResponseWriter, valueSourceParser,
transformer, queryConverter (Noble Paul)
+* SOLR-7005: Spatial 2D heatmap faceting on RPT fields via new facet.heatmap with PNG and
+ 2D int array formats. (David Smiley)
+
Bug Fixes
----------------------
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/component/FacetComponent.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/component/FacetComponent.java?rev=1658617&r1=1658616&r2=1658617&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/component/FacetComponent.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/component/FacetComponent.java Tue Feb 10 03:23:18 2015
@@ -51,8 +51,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * TODO!
- *
+ * Computes facets -- aggregations with counts of terms or ranges over the whole search results.
*
* @since solr 1.3
*/
@@ -66,9 +65,9 @@ public class FacetComponent extends Sear
private static final String PIVOT_REFINE_PREFIX = "{!"+PivotFacet.REFINE_PARAM+"=";
/**
- * incrememented counter used to track the values being refined in a given request.
+ * Incremented counter used to track the values being refined in a given request.
* This counter is used in conjunction with {@link PivotFacet#REFINE_PARAM} to identify
- * which refinement values are associated with which pivots
+ * which refinement values are associated with which pivots.
*/
int pivotRefinementCounter = 0;
@@ -214,6 +213,7 @@ public class FacetComponent extends Sear
shardsRefineRequest.params.set(FacetParams.FACET, "true");
shardsRefineRequest.params.remove(FacetParams.FACET_FIELD);
shardsRefineRequest.params.remove(FacetParams.FACET_QUERY);
+ //TODO remove interval faceting, and ranges and heatmap too?
for (int i = 0; i < distribFieldFacetRefinements.size();) {
String facetCommand = distribFieldFacetRefinements.get(i++);
@@ -318,6 +318,8 @@ public class FacetComponent extends Sear
modifyRequestForRangeFacets(sreq, fi);
modifyRequestForPivotFacets(rb, sreq, fi.pivotFacets);
+
+ SpatialHeatmapFacets.distribModifyRequest(sreq, fi.heatmapFacets);
sreq.params.remove(FacetParams.FACET_MINCOUNT);
sreq.params.remove(FacetParams.FACET_OFFSET);
@@ -332,17 +334,11 @@ public class FacetComponent extends Sear
// we must get all the range buckets back in order to have coherent lists at the end, see SOLR-6154
private void modifyRequestForRangeFacets(ShardRequest sreq, FacetInfo fi) {
// Collect all the range fields.
- if (sreq.params.getParams(FacetParams.FACET_RANGE) == null) {
- return;
- }
- List<String> rangeFields = new ArrayList<>();
- for (String field : sreq.params.getParams(FacetParams.FACET_RANGE)) {
- rangeFields.add(field);
- }
-
- for (String field : rangeFields) {
- sreq.params.remove("f." + field + ".facet.mincount");
- sreq.params.add("f." + field + ".facet.mincount", "0");
+ final String[] fields = sreq.params.getParams(FacetParams.FACET_RANGE);
+ if (fields != null) {
+ for (String field : fields) {
+ sreq.params.set("f." + field + ".facet.mincount", "0");
+ }
}
}
@@ -550,6 +546,9 @@ public class FacetComponent extends Sear
// refinement reqs still needed (below) once we've considered every shard
doDistribPivots(rb, shardNum, facet_counts);
+ // Distributed facet_heatmaps
+ SpatialHeatmapFacets.distribHandleResponse(fi.heatmapFacets, facet_counts);
+
} // end for-each-response-in-shard-request...
// refine each pivot based on the new shard data
@@ -1046,6 +1045,8 @@ public class FacetComponent extends Sear
facet_counts.add("facet_dates", fi.dateFacets);
facet_counts.add("facet_ranges", fi.rangeFacets);
facet_counts.add("facet_intervals", fi.intervalFacets);
+ facet_counts.add(SpatialHeatmapFacets.RESPONSE_KEY,
+ SpatialHeatmapFacets.distribFinish(fi.heatmapFacets, rb));
if (fi.pivotFacets != null && fi.pivotFacets.size() > 0) {
facet_counts.add(PIVOT_KEY, createPivotFacetOutput(rb));
@@ -1112,6 +1113,7 @@ public class FacetComponent extends Sear
= new SimpleOrderedMap<>();
public SimpleOrderedMap<PivotFacet> pivotFacets
= new SimpleOrderedMap<>();
+ public LinkedHashMap<String,SpatialHeatmapFacets.HeatmapFacet> heatmapFacets;
void parse(SolrParams params, ResponseBuilder rb) {
queryFacets = new LinkedHashMap<>();
@@ -1142,6 +1144,8 @@ public class FacetComponent extends Sear
pivotFacets.add(pf.getKey(), pf);
}
}
+
+ heatmapFacets = SpatialHeatmapFacets.distribParse(params, rb);
}
}
Copied: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/component/SpatialHeatmapFacets.java (from r1658614, lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/SpatialHeatmapFacets.java)
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/component/SpatialHeatmapFacets.java?p2=lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/component/SpatialHeatmapFacets.java&p1=lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/SpatialHeatmapFacets.java&r1=1658614&r2=1658617&rev=1658617&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/SpatialHeatmapFacets.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/component/SpatialHeatmapFacets.java Tue Feb 10 03:23:18 2015
@@ -187,7 +187,7 @@ public class SpatialHeatmapFacets {
public List<Integer> get(final int rowIdx) {//top-down remember; the heatmap.counts is bottom up
//check if all zeroes and return null if so
boolean hasNonZero = false;
- int y = rows - rowIdx - 1;//flip direction for 'y'
+ final int y = rows - rowIdx - 1;//flip direction for 'y'
for (int c = 0; c < columns; c++) {
if (counts[c * rows + y] > 0) {
hasNonZero = true;
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/request/SimpleFacets.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/request/SimpleFacets.java?rev=1658617&r1=1658616&r2=1658617&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/request/SimpleFacets.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/request/SimpleFacets.java Tue Feb 10 03:23:18 2015
@@ -72,6 +72,7 @@ import org.apache.solr.common.util.Named
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.common.util.StrUtils;
import org.apache.solr.handler.component.ResponseBuilder;
+import org.apache.solr.handler.component.SpatialHeatmapFacets;
import org.apache.solr.request.IntervalFacets.FacetInterval;
import org.apache.solr.schema.BoolField;
import org.apache.solr.schema.DateRangeField;
@@ -259,7 +260,7 @@ public class SimpleFacets {
facetResponse.add("facet_dates", getFacetDateCounts());
facetResponse.add("facet_ranges", getFacetRangeCounts());
facetResponse.add("facet_intervals", getFacetIntervalCounts());
-
+ facetResponse.add(SpatialHeatmapFacets.RESPONSE_KEY, getHeatmapCounts());
} catch (IOException e) {
throw new SolrException(ErrorCode.SERVER_ERROR, e);
} catch (SyntaxError e) {
@@ -1519,5 +1520,22 @@ public class SimpleFacets {
return res;
}
+ private NamedList getHeatmapCounts() throws IOException, SyntaxError {
+ final NamedList<Object> resOuter = new SimpleOrderedMap<>();
+ String[] unparsedFields = rb.req.getParams().getParams(FacetParams.FACET_HEATMAP);
+ if (unparsedFields == null || unparsedFields.length == 0) {
+ return resOuter;
+ }
+ if (params.getBool(GroupParams.GROUP_FACET, false)) {
+ throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
+ "Heatmaps can't be used with " + GroupParams.GROUP_FACET);
+ }
+ for (String unparsedField : unparsedFields) {
+ parseParams(FacetParams.FACET_HEATMAP, unparsedField); // populates facetValue, rb, params, docs
+
+ resOuter.add(key, SpatialHeatmapFacets.getHeatmapForField(key, facetValue, rb, params, docs));
+ }
+ return resOuter;
+ }
}
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/util/SpatialUtils.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/util/SpatialUtils.java?rev=1658617&r1=1658616&r2=1658617&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/util/SpatialUtils.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/util/SpatialUtils.java Tue Feb 10 03:23:18 2015
@@ -17,9 +17,13 @@ package org.apache.solr.util;
* limitations under the License.
*/
+import java.text.ParseException;
+
import com.spatial4j.core.context.SpatialContext;
import com.spatial4j.core.exception.InvalidShapeException;
import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Rectangle;
+import com.spatial4j.core.shape.Shape;
import org.apache.solr.common.SolrException;
/** Utility methods pertaining to spatial. */
@@ -27,6 +31,28 @@ public class SpatialUtils {
private SpatialUtils() {}
+ /**
+ * Parses a 'geom' parameter (might also be used to parse shapes for indexing). {@code geomStr} can either be WKT or
+ * a rectangle-range syntax (see {@link #parseRectangle(String, com.spatial4j.core.context.SpatialContext)}.
+ */
+ public static Shape parseGeomSolrException(String geomStr, SpatialContext ctx) {
+ if (geomStr.length() == 0) {
+ throw new IllegalArgumentException("0-length geometry string");
+ }
+ char c = geomStr.charAt(0);
+ if (c == '[' || c == '{') {
+ return parseRectangeSolrException(geomStr, ctx);
+ }
+ //TODO parse a raw point?
+ try {
+ return ctx.readShapeFromWkt(geomStr);
+ } catch (ParseException e) {
+ throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
+ "Expecting WKT or '[minPoint TO maxPoint]': " + e, e);
+ }
+
+ }
+
/** Parses either "lat, lon" (spaces optional on either comma side) or "x y" style formats. Spaces can be basically
* anywhere. And not any whitespace, just the space char.
*
@@ -37,8 +63,6 @@ public class SpatialUtils {
*/
public static Point parsePoint(String str, SpatialContext ctx) throws InvalidShapeException {
//note we don't do generic whitespace, just a literal space char detection
- //TODO: decide on if we should pick one format decided by ctx.isGeo()
- // Perhaps 5x use isGeo; 4x use either?
try {
double x, y;
str = str.trim();//TODO use findIndexNotSpace instead?
@@ -89,4 +113,53 @@ public class SpatialUtils {
throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, message, e);
}
}
+
+ /**
+ * Parses {@code str} in the format of '[minPoint TO maxPoint]' where {@code minPoint} is the lower left corner
+ * and maxPoint is the upper-right corner of the bounding box. Both corners may optionally be wrapped with a quote
+ * and then it's parsed via {@link #parsePoint(String, com.spatial4j.core.context.SpatialContext)}.
+ * @param str Non-null; may *not* have leading or trailing spaces
+ * @param ctx Non-null
+ * @return the Rectangle
+ * @throws InvalidShapeException If for any reason there was a problem parsing the string or creating the rectangle.
+ */
+ public static Rectangle parseRectangle(String str, SpatialContext ctx) throws InvalidShapeException {
+ //note we don't do generic whitespace, just a literal space char detection
+ try {
+ int toIdx = str.indexOf(" TO ");
+ if (toIdx == -1 || str.charAt(0) != '[' || str.charAt(str.length() - 1) != ']') {
+ throw new InvalidShapeException("expecting '[bottomLeft TO topRight]'");
+ }
+ String leftPart = unwrapQuotes(str.substring(1, toIdx).trim());
+ String rightPart = unwrapQuotes(str.substring(toIdx + " TO ".length(), str.length() - 1).trim());
+ return ctx.makeRectangle(parsePoint(leftPart, ctx), parsePoint(rightPart, ctx));
+ } catch (InvalidShapeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new InvalidShapeException(e.toString(), e);
+ }
+ }
+
+ /**
+ * Calls {@link #parseRectangle(String, com.spatial4j.core.context.SpatialContext)} and wraps the exception with
+ * {@link org.apache.solr.common.SolrException} with a helpful message.
+ */
+ public static Rectangle parseRectangeSolrException(String externalVal, SpatialContext ctx) throws SolrException {
+ try {
+ return parseRectangle(externalVal, ctx);
+ } catch (InvalidShapeException e) {
+ String message = e.getMessage();
+ if (!message.contains(externalVal))
+ message = "Can't parse rectangle '" + externalVal + "' because: " + message;
+ throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, message, e);
+ }
+ }
+
+ private static String unwrapQuotes(String str) {
+ if (str.length() >= 2 && str.charAt(0) == '\"' && str.charAt(str.length()-1) == '\"') {
+ return str.substring(1, str.length()-1);
+ }
+ return str;
+ }
+
}
Modified: lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/TestGroupingSearch.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/TestGroupingSearch.java?rev=1658617&r1=1658616&r2=1658617&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/TestGroupingSearch.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/TestGroupingSearch.java Tue Feb 10 03:23:18 2015
@@ -17,9 +17,20 @@
package org.apache.solr;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
import org.apache.lucene.index.LogDocMergePolicy;
-import org.noggit.JSONUtil;
-import org.noggit.ObjectBuilder;
import org.apache.solr.client.solrj.impl.BinaryResponseParser;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.GroupParams;
@@ -32,25 +43,15 @@ import org.apache.solr.schema.IndexSchem
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
+import org.noggit.JSONUtil;
+import org.noggit.ObjectBuilder;
public class TestGroupingSearch extends SolrTestCaseJ4 {
public static final String FOO_STRING_FIELD = "foo_s1";
public static final String SMALL_STRING_FIELD = "small_s1";
public static final String SMALL_INT_FIELD = "small_i";
+ static final String EMPTY_FACETS = "'facet_dates':{},'facet_ranges':{},'facet_intervals':{},'facet_heatmaps':{}";
@BeforeClass
public static void beforeTests() throws Exception {
@@ -317,7 +318,7 @@ public class TestGroupingSearch extends
assertJQ(
req,
"/grouped=={'value1_s1':{'matches':5,'groups':[{'groupValue':'1','doclist':{'numFound':3,'start':0,'docs':[{'id':'1'}]}}]}}",
- "/facet_counts=={'facet_queries':{},'facet_fields':{'value3_s1':['a',3,'b',2]},'facet_dates':{},'facet_ranges':{},'facet_intervals':{}}"
+ "/facet_counts=={'facet_queries':{},'facet_fields':{'value3_s1':['a',3,'b',2]}," + EMPTY_FACETS + "}"
);
// Facet counts based on groups
@@ -326,7 +327,7 @@ public class TestGroupingSearch extends
assertJQ(
req,
"/grouped=={'value1_s1':{'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':{},'facet_intervals':{}}"
+ "/facet_counts=={'facet_queries':{},'facet_fields':{'value3_s1':['a',1,'b',1]}," + EMPTY_FACETS + "}"
);
// Facet counts based on groups and with group.func. This should trigger FunctionAllGroupHeadsCollector
@@ -335,7 +336,7 @@ public class TestGroupingSearch extends
assertJQ(
req,
"/grouped=={'strdist(1,value1_s1,edit)':{'matches':5,'groups':[{'groupValue':1.0,'doclist':{'numFound':3,'start':0,'docs':[{'id':'1'}]}}]}}",
- "/facet_counts=={'facet_queries':{},'facet_fields':{'value3_s1':['a',1,'b',1]},'facet_dates':{},'facet_ranges':{},'facet_intervals':{}}"
+ "/facet_counts=={'facet_queries':{},'facet_fields':{'value3_s1':['a',1,'b',1]}," + EMPTY_FACETS + "}"
);
// Facet counts based on groups without sort on an int field.
@@ -344,7 +345,7 @@ public class TestGroupingSearch extends
assertJQ(
req,
"/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':{},'facet_intervals':{}}"
+ "/facet_counts=={'facet_queries':{},'facet_fields':{'value3_s1':['a',1,'b',1]}," + EMPTY_FACETS + "}"
);
// Multi select facets AND group.truncate=true
@@ -353,7 +354,7 @@ public class TestGroupingSearch extends
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':{},'facet_intervals':{}}"
+ "/facet_counts=={'facet_queries':{},'facet_fields':{'value3_s1':['a',1,'b',1]}," + EMPTY_FACETS + "}"
);
// Multi select facets AND group.truncate=false
@@ -362,7 +363,7 @@ public class TestGroupingSearch extends
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':{},'facet_intervals':{}}"
+ "/facet_counts=={'facet_queries':{},'facet_fields':{'value3_s1':['a',3,'b',2]}," + EMPTY_FACETS + "}"
);
// Multi select facets AND group.truncate=true
@@ -371,7 +372,7 @@ public class TestGroupingSearch extends
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':{},'facet_intervals':{}}"
+ "/facet_counts=={'facet_queries':{},'facet_fields':{'value3_s1':['a',1,'b',1]}," + EMPTY_FACETS + "}"
);
}
@@ -394,7 +395,7 @@ public class TestGroupingSearch extends
assertJQ(
req,
"/grouped=={'cat_sI':{'matches':2,'groups':[{'groupValue':'a','doclist':{'numFound':1,'start':0,'docs':[{'id':'5'}]}}]}}",
- "/facet_counts=={'facet_queries':{'LW1':2,'LM1':2,'LM3':2},'facet_fields':{},'facet_dates':{},'facet_ranges':{},'facet_intervals':{}}"
+ "/facet_counts=={'facet_queries':{'LW1':2,'LM1':2,'LM3':2},'facet_fields':{}," + EMPTY_FACETS + "}"
);
}
Modified: lucene/dev/branches/branch_5x/solr/solrj/src/java/org/apache/solr/common/params/FacetParams.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/solrj/src/java/org/apache/solr/common/params/FacetParams.java?rev=1658617&r1=1658616&r2=1658617&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/solrj/src/java/org/apache/solr/common/params/FacetParams.java (original)
+++ lucene/dev/branches/branch_5x/solr/solrj/src/java/org/apache/solr/common/params/FacetParams.java Tue Feb 10 03:23:18 2015
@@ -17,11 +17,11 @@
package org.apache.solr.common.params;
-import org.apache.solr.common.SolrException;
-
import java.util.EnumSet;
import java.util.Locale;
+import org.apache.solr.common.SolrException;
+
/**
* Facet parameters
*/
@@ -282,6 +282,41 @@ public interface FacetParams {
*/
public static final String FACET_INTERVAL_SET = FACET_INTERVAL + ".set";
+ /** A spatial RPT field to generate a 2D "heatmap" (grid of facet counts) on. Just like the other faceting types,
+ * this may include a 'key' or local-params to facet multiple times. All parameters with this suffix can be
+ * overridden on a per-field basis. */
+ public static final String FACET_HEATMAP = "facet.heatmap";
+
+ /** The format of the heatmap: either png or ints2D (default). */
+ public static final String FACET_HEATMAP_FORMAT = FACET_HEATMAP + ".format";
+
+ /** The region the heatmap should minimally enclose. It defaults to the world if not set. The format can either be
+ * a minimum to maximum point range format: <pre>["-150 10" TO "-100 30"]</pre> (the first is bottom-left and second
+ * is bottom-right, both of which are parsed as points are parsed). OR, any WKT can be provided and it's bounding
+ * box will be taken. */
+ public static final String FACET_HEATMAP_GEOM = FACET_HEATMAP + ".geom";
+
+ /** Specify the heatmap grid level explicitly, instead of deriving it via distErr or distErrPct. */
+ public static final String FACET_HEATMAP_LEVEL = FACET_HEATMAP + ".gridLevel";
+
+ /** Used to determine the heatmap grid level to compute, defaulting to 0.15. It has the same interpretation of
+ * distErrPct when searching on RPT, but relative to the shape in 'bbox'. It's a fraction (not a %) of the radius of
+ * the shape that grid squares must fit into without exceeding. > 0 and <= 0.5.
+ * Mutually exclusive with distErr & gridLevel. */
+ public static final String FACET_HEATMAP_DIST_ERR_PCT = FACET_HEATMAP + ".distErrPct";
+
+ /** Used to determine the heatmap grid level to compute (optional). It has the same interpretation of maxDistErr or
+ * distErr with RPT. It's an absolute distance (in units of what's specified on the field type) that a grid square
+ * must maximally fit into (width & height). It can be used to to more explicitly specify the maximum grid square
+ * size without knowledge of what particular grid levels translate to. This can in turn be used with
+ * knowledge of the size of 'bbox' to get a target minimum number of grid cells.
+ * Mutually exclusive with distErrPct & gridLevel. */
+ public static final String FACET_HEATMAP_DIST_ERR = FACET_HEATMAP + ".distErr";
+
+ /** The maximum number of cells (grid squares) the client is willing to handle. If this limit would be exceeded, we
+ * throw an error instead. Defaults to 100k. */
+ public static final String FACET_HEATMAP_MAX_CELLS = FACET_HEATMAP + ".maxCells";
+
/**
* An enumeration of the legal values for {@link #FACET_RANGE_OTHER} and {@link #FACET_DATE_OTHER} ...
* <ul>