SOLR-10526: fix facet.heatmap facet exclusion when distributed/sharded

This commit is contained in:
David Smiley 2017-04-26 14:04:35 -04:00
parent 2d2257926c
commit 8a99937980
3 changed files with 32 additions and 27 deletions

View File

@ -253,6 +253,8 @@ Bug Fixes
* SOLR-10480: Full pagination in JSON Facet API using offset does not work. (yonik)
* SOLR-10526: facet.heatmap didn't honor facet exclusions ('ex') for distributed search. (David Smiley)
Other Changes
----------------------

View File

@ -38,10 +38,9 @@ import org.apache.lucene.spatial.query.SpatialArgs;
import org.apache.lucene.spatial.query.SpatialOperation;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.FixedBitSet;
import org.apache.solr.client.solrj.util.ClientUtils;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.FacetParams;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
@ -291,38 +290,20 @@ public class SpatialHeatmapFacets {
* {@link org.apache.solr.handler.component.SearchComponent#modifyRequest(ResponseBuilder, SearchComponent, ShardRequest)}. */
public static void distribModifyRequest(ShardRequest sreq, LinkedHashMap<String, HeatmapFacet> heatmapFacets) {
// Set the format to PNG because it's compressed and it's the only format we have code to read at the moment.
// Changing a param is sadly tricky because field-specific params can show up as local-params (highest precedence)
// or as f.key.facet.heatmap.whatever. Ugh. So we re-write the facet.heatmap list with the local-params
// moved out to the "f.key." prefix, but we need to keep the key local-param because that's the only way to
// set an output key. This approach means we only need to know about the parameter we're changing, not of
// all possible heatmap params.
// We re-write the facet.heatmap list with PNG format in local-params where it has highest precedence.
//Remove existing heatmap field param vals; we will rewrite
sreq.params.remove(FacetParams.FACET_HEATMAP);
for (Map.Entry<String, HeatmapFacet> entry : heatmapFacets.entrySet()) {
final String key = entry.getKey();
final HeatmapFacet facet = entry.getValue();
for (HeatmapFacet facet : heatmapFacets.values()) {
//add heatmap field param
if (!key.equals(facet.facetOn)) {
sreq.params.add(FacetParams.FACET_HEATMAP,
"{!" + CommonParams.OUTPUT_KEY + "=" + ClientUtils.encodeLocalParamVal(key) + "}" + facet.facetOn);
} else {
sreq.params.add(FacetParams.FACET_HEATMAP, facet.facetOn);
}
// Turn local-params into top-level f.key.param=value style params
ModifiableSolrParams newLocalParams = new ModifiableSolrParams();
if (facet.localParams != null) {
final Iterator<String> localNameIter = facet.localParams.getParameterNamesIterator();
while (localNameIter.hasNext()) {
String pname = localNameIter.next();
if (!pname.startsWith(FacetParams.FACET_HEATMAP)) {
continue; // could be 'key', or 'v' even
}
String pval = facet.localParams.get(pname);
sreq.params.set("f." + key + "." + pname, pval);
}
newLocalParams.add(facet.localParams);
}
// Set format to PNG; it's the only one we parse
sreq.params.set("f." + key + "." + FacetParams.FACET_HEATMAP_FORMAT, FORMAT_PNG);
newLocalParams.set(FacetParams.FACET_HEATMAP_FORMAT, FORMAT_PNG);
sreq.params.add(FacetParams.FACET_HEATMAP,
newLocalParams.toLocalParamsString() + facet.facetOn);
}
}

View File

@ -119,6 +119,28 @@ public class SpatialHeatmapFacetsTest extends BaseDistributedSearchTestCase {
counts
);
// now this time we add a filter query and exclude it
QueryResponse response = query(params(baseParams,
"fq", "{!tag=excludeme}id:0", // filter to only be id:0
FacetParams.FACET_HEATMAP, "{!ex=excludeme}" + FIELD, // exclude the filter
FacetParams.FACET_HEATMAP_GEOM, "[\"50 20\" TO \"180 90\"]",
FacetParams.FACET_HEATMAP_LEVEL, "4"));
assertEquals(1, response.getResults().getNumFound());// because of our 'fq'
hmObj = getHmObj(response);
counts = (List<List<Integer>>) hmObj.get("counts_ints2D");
assertEquals(
Arrays.asList( // same counts as before
Arrays.asList(0, 0, 2, 1, 0, 0),
Arrays.asList(0, 0, 1, 1, 0, 0),
Arrays.asList(0, 1, 1, 1, 0, 0),
Arrays.asList(0, 0, 1, 1, 0, 0),
Arrays.asList(0, 0, 1, 1, 0, 0),
null,
null
),
counts
);
// test using a circle input shape
hmObj = getHmObj(query(params(baseParams,
FacetParams.FACET_HEATMAP_GEOM, "BUFFER(POINT(110 40), 7)",