You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by sh...@apache.org on 2015/07/08 13:05:28 UTC
svn commit: r1689839 [3/3] - in /lucene/dev/branches/branch_5x: ./ solr/
solr/core/ solr/core/src/java/org/apache/solr/handler/
solr/core/src/java/org/apache/solr/handler/component/
solr/core/src/java/org/apache/solr/request/ solr/core/src/java/org/apa...
Modified: lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/handler/component/DistributedFacetPivotSmallTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/handler/component/DistributedFacetPivotSmallTest.java?rev=1689839&r1=1689838&r2=1689839&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/handler/component/DistributedFacetPivotSmallTest.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/handler/component/DistributedFacetPivotSmallTest.java Wed Jul 8 11:05:27 2015
@@ -21,17 +21,19 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
+import junit.framework.AssertionFailedError;
import org.apache.solr.BaseDistributedSearchTestCase;
import org.apache.solr.client.solrj.response.FieldStatsInfo;
import org.apache.solr.client.solrj.response.PivotField;
import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.client.solrj.response.RangeFacet;
import org.apache.solr.common.params.FacetParams;
-import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.params.ModifiableSolrParams;
-
-import junit.framework.AssertionFailedError;
+import org.apache.solr.common.params.SolrParams;
import org.junit.Test;
public class DistributedFacetPivotSmallTest extends BaseDistributedSearchTestCase {
@@ -66,7 +68,7 @@ public class DistributedFacetPivotSmallT
handle.clear();
handle.put("QTime", SKIPVAL);
handle.put("timestamp", SKIPVAL);
- handle.put("maxScore", SKIPVAL);
+ handle.put("maxScore", SKIPVAL);
final ModifiableSolrParams params = new ModifiableSolrParams();
@@ -338,6 +340,16 @@ public class DistributedFacetPivotSmallT
doTestDeepPivotStats(true); // just the mean price stat
doTestPivotStatsFromOneShard();
+
+ testFacetPivotRange();
+
+ testFacetPivotQuery();
+
+ testNegativeFacetQuery();
+
+ testNegativeRangeQuery();
+
+ testPivotFacetRangeAndQuery();
}
/**
@@ -439,6 +451,986 @@ public class DistributedFacetPivotSmallT
}
}
+ private void testFacetPivotRange() throws Exception {
+ final ModifiableSolrParams params = new ModifiableSolrParams();
+ setDistributedParams(params);
+ params.add("q", "*:*");
+ params.add("facet", "true");
+ params.add("facet.pivot", "{!range=s1}place_t,company_t");
+ params.add("facet.range", "{!tag=s1 key=price}price_ti");
+ params.add("facet.range.start", "0");
+ params.add("facet.range.end", "100");
+ params.add("facet.range.gap", "20");
+
+ QueryResponse rsp = queryServer(params);
+
+ List<PivotField> expectedPlacePivots = new UnorderedEqualityArrayList<PivotField>();
+ List<PivotField> expectedCardiffPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedCardiffPivots.add(new ComparablePivotField("company_t",
+ "microsoft", 2, null, null, createExpectedRange("price", 0, 100,
+ 20, 1, 0, 0, 0, 0)));
+ expectedCardiffPivots.add(new ComparablePivotField("company_t", "null", 2,
+ null, null, createExpectedRange("price", 0, 100, 20, 0, 1, 0, 0,
+ 0)));
+ expectedCardiffPivots.add(new ComparablePivotField("company_t", "bbc", 2,
+ null, null, createExpectedRange("price", 0, 100, 20, 0, 1, 0, 0,
+ 0)));
+ expectedCardiffPivots.add(new ComparablePivotField("company_t", "polecat",
+ 3, null, null, createExpectedRange("price", 0, 100, 20, 1, 1, 0,
+ 0, 0)));
+ expectedCardiffPivots.add(new ComparablePivotField("company_t", "fujitsu",
+ 1, null, null, createExpectedRange("price", 0, 100, 20, 0, 0, 0,
+ 0, 0)));
+ List<PivotField> expectedDublinPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "polecat",
+ 4, null, null, createExpectedRange("price", 0, 100, 20, 2, 1, 0,
+ 0, 0)));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "microsoft",
+ 4, null, null, createExpectedRange("price", 0, 100, 20, 2, 1, 0,
+ 0, 0)));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "null", 3,
+ null, null, createExpectedRange("price", 0, 100, 20, 1, 1, 0, 0,
+ 0)));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "fujitsu",
+ 2, null, null, createExpectedRange("price", 0, 100, 20, 0, 1, 0,
+ 0, 0)));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "bbc", 1,
+ null, null, createExpectedRange("price", 0, 100, 20, 0, 0, 0, 0,
+ 0)));
+ List<PivotField> expectedLondonPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "polecat",
+ 3, null, null, createExpectedRange("price", 0, 100, 20, 0, 2, 0,
+ 0, 0)));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "microsoft",
+ 2, null, null, createExpectedRange("price", 0, 100, 20, 0, 1, 0,
+ 0, 0)));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "fujitsu",
+ 2, null, null, createExpectedRange("price", 0, 100, 20, 0, 1, 0,
+ 0, 0)));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "null", 3,
+ null, null, createExpectedRange("price", 0, 100, 20, 0, 2, 0, 0,
+ 0)));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "bbc", 2,
+ null, null, createExpectedRange("price", 0, 100, 20, 0, 1, 0, 0,
+ 0)));
+ List<PivotField> expectedLAPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedLAPivots.add(new ComparablePivotField("company_t", "microsoft", 2,
+ null, null, createExpectedRange("price", 0, 100, 20, 0, 1, 0, 0,
+ 0)));
+ expectedLAPivots.add(new ComparablePivotField("company_t", "fujitsu", 2,
+ null, null, createExpectedRange("price", 0, 100, 20, 0, 1, 0, 0,
+ 0)));
+ expectedLAPivots.add(new ComparablePivotField("company_t", "null", 2, null,
+ null, createExpectedRange("price", 0, 100, 20, 0, 1, 0, 0, 0)));
+ expectedLAPivots.add(new ComparablePivotField("company_t", "bbc", 1, null,
+ null, createExpectedRange("price", 0, 100, 20, 0, 0, 0, 0, 0)));
+ expectedLAPivots.add(new ComparablePivotField("company_t", "polecat", 2,
+ null, null, createExpectedRange("price", 0, 100, 20, 0, 1, 0, 0,
+ 0)));
+ List<PivotField> expectedKrakowPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedKrakowPivots.add(new ComparablePivotField("company_t", "polecat",
+ 2, null, null, createExpectedRange("price", 0, 100, 20, 0, 1, 0,
+ 0, 0)));
+ expectedKrakowPivots.add(new ComparablePivotField("company_t", "bbc", 2,
+ null, null, createExpectedRange("price", 0, 100, 20, 0, 1, 0, 0,
+ 0)));
+ expectedKrakowPivots.add(new ComparablePivotField("company_t", "null", 3,
+ null, null, createExpectedRange("price", 0, 100, 20, 0, 1, 0, 0,
+ 0)));
+ expectedKrakowPivots.add(new ComparablePivotField("company_t", "fujitsu",
+ 1, null, null, createExpectedRange("price", 0, 100, 20, 0, 0, 0,
+ 0, 0)));
+ expectedKrakowPivots.add(new ComparablePivotField("company_t", "microsoft",
+ 1, null, null, createExpectedRange("price", 0, 100, 20, 0, 0, 0,
+ 0, 0)));
+ List<PivotField> expectedCorkPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedCorkPivots.add(new ComparablePivotField("company_t", "fujitsu", 1,
+ null, null, createExpectedRange("price", 0, 100, 20, 0, 0, 0, 0,
+ 0)));
+ expectedCorkPivots.add(new ComparablePivotField("company_t", "rte", 1,
+ null, null, createExpectedRange("price", 0, 100, 20, 0, 0, 0, 0,
+ 0)));
+
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "dublin", 4,
+ expectedDublinPivots, null, createExpectedRange("price", 0, 100,
+ 20, 2, 1, 0, 0, 0)));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "cardiff", 3,
+ expectedCardiffPivots, null, createExpectedRange("price", 0, 100,
+ 20, 1, 1, 0, 0, 0)));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "london", 4,
+ expectedLondonPivots, null, createExpectedRange("price", 0, 100,
+ 20, 0, 3, 0, 0, 0)));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "la", 3,
+ expectedLAPivots, null, createExpectedRange("price", 0, 100, 20,
+ 0, 1, 0, 0, 0)));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "krakow", 3,
+ expectedKrakowPivots, null, createExpectedRange("price", 0, 100,
+ 20, 0, 1, 0, 0, 0)));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "cork", 1,
+ expectedCorkPivots, null, createExpectedRange("price", 0, 100,
+ 20, 0, 0, 0, 0, 0)));
+
+ List<PivotField> placePivots = rsp.getFacetPivot().get("place_t,company_t");
+
+ // Useful to check for errors, orders lists and does toString() equality
+ // check
+ testOrderedPivotsStringEquality(expectedPlacePivots, placePivots);
+
+ assertEquals(expectedPlacePivots, placePivots);
+
+ // Test sorting by count
+
+ params.set(FacetParams.FACET_SORT, FacetParams.FACET_SORT_COUNT);
+
+ rsp = queryServer(params);
+
+ placePivots = rsp.getFacetPivot().get("place_t,company_t");
+
+ testCountSorting(placePivots);
+
+ // Test limit
+
+ params.set(FacetParams.FACET_LIMIT, 2);
+
+ rsp = queryServer(params);
+
+ expectedPlacePivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedDublinPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "polecat",
+ 4, null, null, createExpectedRange("price", 0, 100, 20, 2, 1, 0,
+ 0, 0)));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "microsoft",
+ 4, null, null, createExpectedRange("price", 0, 100, 20, 2, 1, 0,
+ 0, 0)));
+ expectedLondonPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "null", 3,
+ null, null, createExpectedRange("price", 0, 100, 20, 0, 2, 0, 0,
+ 0)));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "polecat",
+ 3, null, null, createExpectedRange("price", 0, 100, 20, 0, 2, 0,
+ 0, 0)));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "dublin", 4,
+ expectedDublinPivots, null, createExpectedRange("price", 0, 100,
+ 20, 2, 1, 0, 0, 0)));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "london", 4,
+ expectedLondonPivots, null, createExpectedRange("price", 0, 100,
+ 20, 0, 3, 0, 0, 0)));
+
+ placePivots = rsp.getFacetPivot().get("place_t,company_t");
+
+ assertEquals(expectedPlacePivots, placePivots);
+
+ // Test individual facet.limit values
+ params.remove(FacetParams.FACET_LIMIT);
+
+ params.set("f.place_t." + FacetParams.FACET_LIMIT, 1);
+ params.set("f.company_t." + FacetParams.FACET_LIMIT, 4);
+
+ rsp = queryServer(params);
+
+ expectedPlacePivots = new UnorderedEqualityArrayList<PivotField>();
+
+ expectedDublinPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "microsoft",
+ 4, null, null, createExpectedRange("price", 0, 100, 20, 2, 1, 0,
+ 0, 0)));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "polecat",
+ 4, null, null, createExpectedRange("price", 0, 100, 20, 2, 1, 0,
+ 0, 0)));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "null", 3,
+ null, null, createExpectedRange("price", 0, 100, 20, 1, 1, 0, 0,
+ 0)));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "fujitsu",
+ 2, null, null, createExpectedRange("price", 0, 100, 20, 0, 1, 0,
+ 0, 0)));
+
+ expectedLondonPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "null", 3,
+ null, null, createExpectedRange("price", 0, 100, 20, 0, 2, 0, 0,
+ 0)));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "polecat",
+ 3, null, null, createExpectedRange("price", 0, 100, 20, 0, 2, 0,
+ 0, 0)));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "bbc", 2,
+ null, null, createExpectedRange("price", 0, 100, 20, 0, 1, 0, 0,
+ 0)));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "fujitsu",
+ 2, null, null, createExpectedRange("price", 0, 100, 20, 0, 1, 0,
+ 0, 0)));
+
+ expectedCardiffPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedCardiffPivots.add(new ComparablePivotField("company_t", "polecat",
+ 3, null, null, createExpectedRange("price", 0, 100, 20, 1, 1, 0,
+ 0, 0)));
+
+ expectedKrakowPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedKrakowPivots.add(new ComparablePivotField("company_t", "null", 3,
+ null, null, createExpectedRange("price", 0, 100, 20, 0, 1, 0, 0,
+ 0)));
+
+ expectedLAPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedLAPivots.add(new ComparablePivotField("company_t", "fujitsu", 2,
+ null, null, createExpectedRange("price", 0, 100, 20, 0, 1, 0, 0,
+ 0)));
+
+ expectedCorkPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedCorkPivots.add(new ComparablePivotField("company_t", "fujitsu", 1,
+ null, null, createExpectedRange("price", 0, 100, 20, 0, 0, 0, 0,
+ 0)));
+
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "dublin", 4,
+ expectedDublinPivots, null, createExpectedRange("price", 0, 100,
+ 20, 2, 1, 0, 0, 0)));
+
+ placePivots = rsp.getFacetPivot().get("place_t,company_t");
+ assertEquals(expectedPlacePivots, placePivots);
+
+ params.remove("f.company_t." + FacetParams.FACET_LIMIT);
+ params.remove("f.place_t." + FacetParams.FACET_LIMIT);
+ params.set(FacetParams.FACET_LIMIT, 2);
+
+ // Test facet.missing=true with diff sorts
+
+ index("id", 777); // NOTE: id=25 has no place as well
+ commit();
+
+ SolrParams missingA = params("q", "*:*", "rows", "0", "facet", "true",
+ "facet.pivot", "place_t,company_t",
+ // default facet.sort
+ FacetParams.FACET_MISSING, "true");
+ SolrParams missingB = SolrParams.wrapDefaults(missingA,
+ params(FacetParams.FACET_LIMIT, "4", "facet.sort", "index"));
+ for (SolrParams p : new SolrParams[]{missingA, missingB}) {
+ // in either case, the last pivot option should be the same
+ rsp = query(p);
+ placePivots = rsp.getFacetPivot().get("place_t,company_t");
+ assertTrue("not enough values for pivot: " + p + " => " + placePivots,
+ 1 < placePivots.size());
+ PivotField missing = placePivots.get(placePivots.size() - 1);
+ assertNull("not the missing place value: " + p, missing.getValue());
+ assertEquals("wrong missing place count: " + p, 2, missing.getCount());
+ assertTrue("not enough sub-pivots for missing place: " + p + " => "
+ + missing.getPivot(), 1 < missing.getPivot().size());
+ missing = missing.getPivot().get(missing.getPivot().size() - 1);
+ assertNull("not the missing company value: " + p, missing.getValue());
+ assertEquals("wrong missing company count: " + p, 1, missing.getCount());
+ assertNull("company shouldn't have sub-pivots: " + p, missing.getPivot());
+ }
+
+ // sort=index + mincount + limit
+ for (SolrParams variableParams : new SolrParams[]{
+ // we should get the same results regardless of overrequest
+ params("facet.overrequest.count", "0", "facet.overrequest.ratio", "0"),
+ params()}) {
+
+ SolrParams p = SolrParams.wrapDefaults(
+ params("q", "*:*", "rows", "0", "facet", "true", "facet.pivot",
+ "company_t", "facet.sort", "index", "facet.pivot.mincount", "4",
+ "facet.limit", "4"), variableParams);
+
+ try {
+ List<PivotField> pivots = query(p).getFacetPivot().get("company_t");
+ assertEquals(4, pivots.size());
+ assertEquals("fujitsu", pivots.get(0).getValue());
+ assertEquals(4, pivots.get(0).getCount());
+ assertEquals("microsoft", pivots.get(1).getValue());
+ assertEquals(5, pivots.get(1).getCount());
+ assertEquals("null", pivots.get(2).getValue());
+ assertEquals(6, pivots.get(2).getCount());
+ assertEquals("polecat", pivots.get(3).getValue());
+ assertEquals(6, pivots.get(3).getCount());
+
+ } catch (AssertionFailedError ae) {
+ throw new AssertionError(ae.getMessage() + " <== " + p.toString(), ae);
+ }
+ }
+
+ // sort=index + mincount + limit + offset
+ for (SolrParams variableParams : new SolrParams[]{
+ // we should get the same results regardless of overrequest
+ params("facet.overrequest.count", "0", "facet.overrequest.ratio", "0"),
+ params()}) {
+
+ SolrParams p = SolrParams.wrapDefaults(
+ params("q", "*:*", "rows", "0", "facet", "true", "facet.pivot",
+ "company_t", "facet.sort", "index", "facet.pivot.mincount", "4",
+ "facet.offset", "1", "facet.limit", "4"), variableParams);
+ try {
+ List<PivotField> pivots = query(p).getFacetPivot().get("company_t");
+ assertEquals(3, pivots.size()); // asked for 4, but not enough meet the
+ // mincount
+ assertEquals("microsoft", pivots.get(0).getValue());
+ assertEquals(5, pivots.get(0).getCount());
+ assertEquals("null", pivots.get(1).getValue());
+ assertEquals(6, pivots.get(1).getCount());
+ assertEquals("polecat", pivots.get(2).getValue());
+ assertEquals(6, pivots.get(2).getCount());
+
+ } catch (AssertionFailedError ae) {
+ throw new AssertionError(ae.getMessage() + " <== " + p.toString(), ae);
+ }
+
+ }
+
+ // sort=index + mincount + limit + offset (more permutations)
+ for (SolrParams variableParams : new SolrParams[]{
+ // all of these combinations should result in the same first value
+ params("facet.pivot.mincount", "4", "facet.offset", "2"),
+ params("facet.pivot.mincount", "5", "facet.offset", "1"),
+ params("facet.pivot.mincount", "6", "facet.offset", "0")}) {
+
+ SolrParams p = SolrParams.wrapDefaults(
+ params("q", "*:*", "rows", "0", "facet", "true", "facet.limit", "1",
+ "facet.sort", "index", "facet.overrequest.ratio", "0",
+ "facet.pivot", "company_t"), variableParams);
+
+ try {
+ List<PivotField> pivots = query(p).getFacetPivot().get("company_t");
+ assertEquals(1, pivots.size());
+ assertEquals(pivots.toString(), "null", pivots.get(0).getValue());
+ assertEquals(pivots.toString(), 6, pivots.get(0).getCount());
+
+ } catch (AssertionFailedError ae) {
+ throw new AssertionError(ae.getMessage() + " <== " + p.toString(), ae);
+ }
+ }
+ }
+
+ private void testFacetPivotQuery() throws Exception {
+ final ModifiableSolrParams params = new ModifiableSolrParams();
+ setDistributedParams(params);
+ params.add("q", "*:*");
+ params.add("facet", "true");
+ params.add("facet.pivot", "{!query=s1}place_t,company_t");
+ params.add("facet.query", "{!tag=s1 key=highPrice}price_ti:[25 TO 100]");
+
+ QueryResponse rsp = queryServer(params);
+
+ List<PivotField> expectedPlacePivots = new UnorderedEqualityArrayList<PivotField>();
+ List<PivotField> expectedCardiffPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedCardiffPivots.add(new ComparablePivotField("company_t",
+ "microsoft", 2, null, createExpectedQCount(
+ new String[]{"highPrice"}, new int[]{0}), null));
+ expectedCardiffPivots.add(new ComparablePivotField("company_t", "null", 2,
+ null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{1}), null));
+ expectedCardiffPivots.add(new ComparablePivotField("company_t", "bbc", 2,
+ null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{1}), null));
+ expectedCardiffPivots.add(new ComparablePivotField("company_t", "polecat",
+ 3, null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{1}), null));
+ expectedCardiffPivots.add(new ComparablePivotField("company_t", "fujitsu",
+ 1, null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{0}), null));
+ List<PivotField> expectedDublinPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "polecat",
+ 4, null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{1}), null));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "microsoft",
+ 4, null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{1}), null));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "null", 3,
+ null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{1}), null));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "fujitsu",
+ 2, null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{1}), null));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "bbc", 1,
+ null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{0}), null));
+ List<PivotField> expectedLondonPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "polecat",
+ 3, null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{2}), null));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "microsoft",
+ 2, null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{1}), null));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "fujitsu",
+ 2, null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{1}), null));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "null", 3,
+ null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{2}), null));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "bbc", 2,
+ null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{1}), null));
+ List<PivotField> expectedLAPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedLAPivots.add(new ComparablePivotField("company_t", "microsoft", 2,
+ null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{1}), null));
+ expectedLAPivots.add(new ComparablePivotField("company_t", "fujitsu", 2,
+ null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{1}), null));
+ expectedLAPivots.add(new ComparablePivotField("company_t", "null", 2, null,
+ createExpectedQCount(new String[]{"highPrice"}, new int[]{1}),
+ null));
+ expectedLAPivots.add(new ComparablePivotField("company_t", "bbc", 1, null,
+ createExpectedQCount(new String[]{"highPrice"}, new int[]{0}),
+ null));
+ expectedLAPivots.add(new ComparablePivotField("company_t", "polecat", 2,
+ null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{1}), null));
+ List<PivotField> expectedKrakowPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedKrakowPivots.add(new ComparablePivotField("company_t", "polecat",
+ 2, null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{1}), null));
+ expectedKrakowPivots.add(new ComparablePivotField("company_t", "bbc", 2,
+ null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{1}), null));
+ expectedKrakowPivots.add(new ComparablePivotField("company_t", "null", 3,
+ null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{1}), null));
+ expectedKrakowPivots.add(new ComparablePivotField("company_t", "fujitsu",
+ 1, null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{0}), null));
+ expectedKrakowPivots.add(new ComparablePivotField("company_t", "microsoft",
+ 1, null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{0}), null));
+ List<PivotField> expectedCorkPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedCorkPivots.add(new ComparablePivotField("company_t", "fujitsu", 1,
+ null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{0}), null));
+ expectedCorkPivots.add(new ComparablePivotField("company_t", "rte", 1,
+ null, createExpectedQCount(new String[]{"highPrice"},
+ new int[]{0}), null));
+
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "dublin", 4,
+ expectedDublinPivots, createExpectedQCount(
+ new String[]{"highPrice"}, new int[]{1}), null));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "cardiff", 3,
+ expectedCardiffPivots, createExpectedQCount(
+ new String[]{"highPrice"}, new int[]{1}), null));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "london", 4,
+ expectedLondonPivots, createExpectedQCount(
+ new String[]{"highPrice"}, new int[]{3}), null));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "la", 3,
+ expectedLAPivots, createExpectedQCount(
+ new String[]{"highPrice"}, new int[]{1}), null));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "krakow", 3,
+ expectedKrakowPivots, createExpectedQCount(
+ new String[]{"highPrice"}, new int[]{1}), null));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "cork", 1,
+ expectedCorkPivots, createExpectedQCount(
+ new String[]{"highPrice"}, new int[]{0}), null));
+
+ List<PivotField> placePivots = rsp.getFacetPivot().get("place_t,company_t");
+
+ // Useful to check for errors, orders lists and does toString() equality
+ // check
+ testOrderedPivotsStringEquality(expectedPlacePivots, placePivots);
+
+ assertEquals(expectedPlacePivots, placePivots);
+
+ // Add second query for low price
+ params.add("facet.query", "{!tag=s1 key=lowPrice}price_ti:[0 TO 20]");
+ expectedPlacePivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedCardiffPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedCardiffPivots.add(new ComparablePivotField("company_t",
+ "microsoft", 2, null, createExpectedQCount(new String[]{
+ "highPrice", "lowPrice"}, new int[]{0, 1}), null));
+ expectedCardiffPivots.add(new ComparablePivotField("company_t", "null", 2,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{1, 0}), null));
+ expectedCardiffPivots.add(new ComparablePivotField("company_t", "bbc", 2,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{1, 0}), null));
+ expectedCardiffPivots.add(new ComparablePivotField("company_t", "polecat",
+ 3, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{1, 1}), null));
+ expectedCardiffPivots.add(new ComparablePivotField("company_t", "fujitsu",
+ 1, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{0, 0}), null));
+ expectedDublinPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "polecat",
+ 4, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{1, 2}), null));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "microsoft",
+ 4, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{1, 2}), null));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "null", 3,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{1, 1}), null));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "fujitsu",
+ 2, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{1, 0}), null));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "bbc", 1,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{0, 0}), null));
+ expectedLondonPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "polecat",
+ 3, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{2, 0}), null));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "microsoft",
+ 2, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{1, 0}), null));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "fujitsu",
+ 2, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{1, 0}), null));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "null", 3,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{2, 0}), null));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "bbc", 2,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{1, 0}), null));
+ expectedLAPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedLAPivots.add(new ComparablePivotField("company_t", "microsoft", 2,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{1, 0}), null));
+ expectedLAPivots.add(new ComparablePivotField("company_t", "fujitsu", 2,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{1, 0}), null));
+ expectedLAPivots.add(new ComparablePivotField("company_t", "null", 2, null,
+ createExpectedQCount(new String[]{"highPrice", "lowPrice"},
+ new int[]{1, 0}), null));
+ expectedLAPivots.add(new ComparablePivotField("company_t", "bbc", 1, null,
+ createExpectedQCount(new String[]{"highPrice", "lowPrice"},
+ new int[]{0, 0}), null));
+ expectedLAPivots.add(new ComparablePivotField("company_t", "polecat", 2,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{1, 0}), null));
+ expectedKrakowPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedKrakowPivots.add(new ComparablePivotField("company_t", "polecat",
+ 2, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{1, 0}), null));
+ expectedKrakowPivots.add(new ComparablePivotField("company_t", "bbc", 2,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{1, 0}), null));
+ expectedKrakowPivots.add(new ComparablePivotField("company_t", "null", 3,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{1, 0}), null));
+ expectedKrakowPivots.add(new ComparablePivotField("company_t", "fujitsu",
+ 1, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{0, 0}), null));
+ expectedKrakowPivots.add(new ComparablePivotField("company_t", "microsoft",
+ 1, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{0, 0}), null));
+ expectedCorkPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedCorkPivots.add(new ComparablePivotField("company_t", "fujitsu", 1,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{0, 0}), null));
+ expectedCorkPivots.add(new ComparablePivotField("company_t", "rte", 1,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{0, 0}), null));
+
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "dublin", 4,
+ expectedDublinPivots, createExpectedQCount(new String[]{
+ "highPrice", "lowPrice"}, new int[]{1, 2}), null));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "cardiff", 3,
+ expectedCardiffPivots, createExpectedQCount(new String[]{
+ "highPrice", "lowPrice"}, new int[]{1, 1}), null));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "london", 4,
+ expectedLondonPivots, createExpectedQCount(new String[]{
+ "highPrice", "lowPrice"}, new int[]{3, 0}), null));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "la", 3,
+ expectedLAPivots, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{1, 0}), null));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "krakow", 3,
+ expectedKrakowPivots, createExpectedQCount(new String[]{
+ "highPrice", "lowPrice"}, new int[]{1, 0}), null));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "cork", 1,
+ expectedCorkPivots, createExpectedQCount(new String[]{
+ "highPrice", "lowPrice"}, new int[]{0, 0}), null));
+
+ rsp = queryServer(params);
+
+ placePivots = rsp.getFacetPivot().get("place_t,company_t");
+
+ // Useful to check for errors, orders lists and does toString() equality
+ // check
+ testOrderedPivotsStringEquality(expectedPlacePivots, placePivots);
+ assertEquals(expectedPlacePivots, placePivots);
+
+ // Test sorting by count
+
+ params.set(FacetParams.FACET_SORT, FacetParams.FACET_SORT_COUNT);
+
+ rsp = queryServer(params);
+
+ placePivots = rsp.getFacetPivot().get("place_t,company_t");
+
+ testCountSorting(placePivots);
+
+ // Test limit
+
+ params.set(FacetParams.FACET_LIMIT, 2);
+
+ rsp = queryServer(params);
+
+ expectedPlacePivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedDublinPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "polecat",
+ 4, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{1, 2}), null));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "microsoft",
+ 4, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{1, 2}), null));
+ expectedLondonPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "null", 3,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{2, 0}), null));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "polecat",
+ 3, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{2, 0}), null));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "dublin", 4,
+ expectedDublinPivots, createExpectedQCount(new String[]{
+ "highPrice", "lowPrice"}, new int[]{1, 2}), null));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "london", 4,
+ expectedLondonPivots, createExpectedQCount(new String[]{
+ "highPrice", "lowPrice"}, new int[]{3, 0}), null));
+
+ placePivots = rsp.getFacetPivot().get("place_t,company_t");
+
+ assertEquals(expectedPlacePivots, placePivots);
+
+ // Test individual facet.limit values
+ params.remove(FacetParams.FACET_LIMIT);
+
+ params.set("f.place_t." + FacetParams.FACET_LIMIT, 1);
+ params.set("f.company_t." + FacetParams.FACET_LIMIT, 4);
+
+ rsp = queryServer(params);
+
+ expectedPlacePivots = new UnorderedEqualityArrayList<PivotField>();
+
+ expectedDublinPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "microsoft",
+ 4, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{1, 2}), null));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "polecat",
+ 4, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{1, 2}), null));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "null", 3,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{1, 1}), null));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "fujitsu",
+ 2, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{1, 0}), null));
+
+ expectedLondonPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "null", 3,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{2, 0}), null));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "polecat",
+ 3, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{2, 0}), null));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "bbc", 2,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{1, 0}), null));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "fujitsu",
+ 2, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{1, 0}), null));
+
+ expectedCardiffPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedCardiffPivots.add(new ComparablePivotField("company_t", "polecat",
+ 3, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{1, 1}), null));
+
+ expectedKrakowPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedKrakowPivots.add(new ComparablePivotField("company_t", "null", 3,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{1, 0}), null));
+
+ expectedLAPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedLAPivots.add(new ComparablePivotField("company_t", "fujitsu", 2,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{1, 0}), null));
+
+ expectedCorkPivots = new UnorderedEqualityArrayList<PivotField>();
+ expectedCorkPivots.add(new ComparablePivotField("company_t", "fujitsu", 1,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{0, 0}), null));
+
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "dublin", 4,
+ expectedDublinPivots, createExpectedQCount(new String[]{
+ "highPrice", "lowPrice"}, new int[]{1, 2}), null));
+
+ placePivots = rsp.getFacetPivot().get("place_t,company_t");
+ assertEquals(expectedPlacePivots, placePivots);
+
+ params.remove("f.company_t." + FacetParams.FACET_LIMIT);
+ params.remove("f.place_t." + FacetParams.FACET_LIMIT);
+ params.set(FacetParams.FACET_LIMIT, 2);
+
+ // Test facet.missing=true with diff sorts
+
+ index("id", 777); // NOTE: id=25 has no place as well
+ commit();
+
+ SolrParams missingA = params("q", "*:*", "rows", "0", "facet", "true",
+ "facet.pivot", "place_t,company_t",
+ // default facet.sort
+ FacetParams.FACET_MISSING, "true");
+ SolrParams missingB = SolrParams.wrapDefaults(missingA,
+ params(FacetParams.FACET_LIMIT, "4", "facet.sort", "index"));
+ for (SolrParams p : new SolrParams[]{missingA, missingB}) {
+ // in either case, the last pivot option should be the same
+ rsp = query(p);
+ placePivots = rsp.getFacetPivot().get("place_t,company_t");
+ assertTrue("not enough values for pivot: " + p + " => " + placePivots,
+ 1 < placePivots.size());
+ PivotField missing = placePivots.get(placePivots.size() - 1);
+ assertNull("not the missing place value: " + p, missing.getValue());
+ assertEquals("wrong missing place count: " + p, 2, missing.getCount());
+ assertTrue("not enough sub-pivots for missing place: " + p + " => "
+ + missing.getPivot(), 1 < missing.getPivot().size());
+ missing = missing.getPivot().get(missing.getPivot().size() - 1);
+ assertNull("not the missing company value: " + p, missing.getValue());
+ assertEquals("wrong missing company count: " + p, 1, missing.getCount());
+ assertNull("company shouldn't have sub-pivots: " + p, missing.getPivot());
+ }
+
+ // sort=index + mincount + limit
+ for (SolrParams variableParams : new SolrParams[]{
+ // we should get the same results regardless of overrequest
+ params("facet.overrequest.count", "0", "facet.overrequest.ratio", "0"),
+ params()}) {
+
+ SolrParams p = SolrParams.wrapDefaults(
+ params("q", "*:*", "rows", "0", "facet", "true", "facet.pivot",
+ "company_t", "facet.sort", "index", "facet.pivot.mincount", "4",
+ "facet.limit", "4"), variableParams);
+
+ try {
+ List<PivotField> pivots = query(p).getFacetPivot().get("company_t");
+ assertEquals(4, pivots.size());
+ assertEquals("fujitsu", pivots.get(0).getValue());
+ assertEquals(4, pivots.get(0).getCount());
+ assertEquals("microsoft", pivots.get(1).getValue());
+ assertEquals(5, pivots.get(1).getCount());
+ assertEquals("null", pivots.get(2).getValue());
+ assertEquals(6, pivots.get(2).getCount());
+ assertEquals("polecat", pivots.get(3).getValue());
+ assertEquals(6, pivots.get(3).getCount());
+
+ } catch (AssertionFailedError ae) {
+ throw new AssertionError(ae.getMessage() + " <== " + p.toString(), ae);
+ }
+ }
+
+ // sort=index + mincount + limit + offset
+ for (SolrParams variableParams : new SolrParams[]{
+ // we should get the same results regardless of overrequest
+ params("facet.overrequest.count", "0", "facet.overrequest.ratio", "0"),
+ params()}) {
+
+ SolrParams p = SolrParams.wrapDefaults(
+ params("q", "*:*", "rows", "0", "facet", "true", "facet.pivot",
+ "company_t", "facet.sort", "index", "facet.pivot.mincount", "4",
+ "facet.offset", "1", "facet.limit", "4"), variableParams);
+ try {
+ List<PivotField> pivots = query(p).getFacetPivot().get("company_t");
+ assertEquals(3, pivots.size()); // asked for 4, but not enough meet the
+ // mincount
+ assertEquals("microsoft", pivots.get(0).getValue());
+ assertEquals(5, pivots.get(0).getCount());
+ assertEquals("null", pivots.get(1).getValue());
+ assertEquals(6, pivots.get(1).getCount());
+ assertEquals("polecat", pivots.get(2).getValue());
+ assertEquals(6, pivots.get(2).getCount());
+
+ } catch (AssertionFailedError ae) {
+ throw new AssertionError(ae.getMessage() + " <== " + p.toString(), ae);
+ }
+
+ }
+
+ // sort=index + mincount + limit + offset (more permutations)
+ for (SolrParams variableParams : new SolrParams[]{
+ // all of these combinations should result in the same first value
+ params("facet.pivot.mincount", "4", "facet.offset", "2"),
+ params("facet.pivot.mincount", "5", "facet.offset", "1"),
+ params("facet.pivot.mincount", "6", "facet.offset", "0")}) {
+
+ SolrParams p = SolrParams.wrapDefaults(
+ params("q", "*:*", "rows", "0", "facet", "true", "facet.limit", "1",
+ "facet.sort", "index", "facet.overrequest.ratio", "0",
+ "facet.pivot", "company_t"), variableParams);
+
+ try {
+ List<PivotField> pivots = query(p).getFacetPivot().get("company_t");
+ assertEquals(1, pivots.size());
+ assertEquals(pivots.toString(), "null", pivots.get(0).getValue());
+ assertEquals(pivots.toString(), 6, pivots.get(0).getCount());
+
+ } catch (AssertionFailedError ae) {
+ throw new AssertionError(ae.getMessage() + " <== " + p.toString(), ae);
+ }
+ }
+ }
+
+ private void testPivotFacetRangeAndQuery() throws Exception {
+ SolrParams params = params("q", "*:*",
+ "rows", "0",
+ "facet", "true",
+ "stats", "true",
+ "facet.pivot", "{!range=s1 query=s2 stats=s3}place_t,company_t",
+ "facet.range", "{!tag=s1 key=price}price_ti",
+ "facet.query", "{!tag=s2 key=highPrice}price_ti:[25 TO 100]",
+ "facet.query", "{!tag=s2 key=lowPrice}price_ti:[0 TO 20]",
+ "stats.field", ("{!tag=s3 key=avg_price}price_ti"),
+ "facet.range.start", "0",
+ "facet.range.end", "100",
+ "facet.range.gap", "20",
+ FacetParams.FACET_SORT, FacetParams.FACET_SORT_COUNT,
+ FacetParams.FACET_LIMIT, "2");
+
+ UnorderedEqualityArrayList<PivotField> expectedPlacePivots = new UnorderedEqualityArrayList<>();
+ UnorderedEqualityArrayList<PivotField> expectedDublinPivots = new UnorderedEqualityArrayList<>();
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "polecat",
+ 4, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{1, 2}), createExpectedRange("price", 0, 100, 20, 2, 1, 0,
+ 0, 0)));
+ expectedDublinPivots.add(new ComparablePivotField("company_t", "microsoft",
+ 4, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{1, 2}), createExpectedRange("price", 0, 100, 20, 2, 1, 0,
+ 0, 0)));
+ UnorderedEqualityArrayList<PivotField> expectedLondonPivots = new UnorderedEqualityArrayList<>();
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "null", 3,
+ null, createExpectedQCount(
+ new String[]{"highPrice", "lowPrice"}, new int[]{2, 0}), createExpectedRange("price", 0, 100, 20, 0, 2, 0, 0,
+ 0)));
+ expectedLondonPivots.add(new ComparablePivotField("company_t", "polecat",
+ 3, null, createExpectedQCount(new String[]{"highPrice",
+ "lowPrice"}, new int[]{2, 0}), createExpectedRange("price", 0, 100, 20, 0, 2, 0,
+ 0, 0)));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "dublin", 4,
+ expectedDublinPivots, createExpectedQCount(new String[]{
+ "highPrice", "lowPrice"}, new int[]{1, 2}), createExpectedRange("price", 0, 100,
+ 20, 2, 1, 0, 0, 0)));
+ expectedPlacePivots.add(new ComparablePivotField("place_t", "london", 4,
+ expectedLondonPivots, createExpectedQCount(new String[]{
+ "highPrice", "lowPrice"}, new int[]{3, 0}), createExpectedRange("price", 0, 100,
+ 20, 0, 3, 0, 0, 0)));
+
+ QueryResponse rsp = query(params);
+ List<PivotField> placePivots = rsp.getFacetPivot().get("place_t,company_t");
+ assertEquals(expectedPlacePivots, placePivots);
+
+ PivotField dublinPivotField = placePivots.get(0);
+ assertEquals("dublin", dublinPivotField.getValue());
+ assertEquals(4, dublinPivotField.getCount());
+
+ PivotField microsoftPivotField = dublinPivotField.getPivot().get(0);
+ assertEquals("microsoft", microsoftPivotField.getValue());
+ assertEquals(4, microsoftPivotField.getCount());
+
+ FieldStatsInfo dublinMicrosoftStatsInfo = microsoftPivotField.getFieldStatsInfo().get("avg_price");
+ assertEquals(21.0, (double) dublinMicrosoftStatsInfo.getMean(), 0.1E-7);
+ assertEquals(15.0, dublinMicrosoftStatsInfo.getMin());
+ assertEquals(29.0, dublinMicrosoftStatsInfo.getMax());
+ assertEquals(3, (long) dublinMicrosoftStatsInfo.getCount());
+ assertEquals(1, (long) dublinMicrosoftStatsInfo.getMissing());
+ assertEquals(63.0, dublinMicrosoftStatsInfo.getSum());
+ assertEquals(1427.0, dublinMicrosoftStatsInfo.getSumOfSquares(), 0.1E-7);
+ assertEquals(7.211102550927978, dublinMicrosoftStatsInfo.getStddev(), 0.1E-7);
+ }
+
+ private void testNegativeFacetQuery() throws Exception {
+ // this should not hang facet.query under the pivot
+ SolrParams params = params("q", "*:*",
+ "rows", "0",
+ "stats", "true",
+ "facet.query", "{!tag=ttt}price_ti:[25 TO 100]",
+ "facet", "true",
+ "facet.pivot", "{!query=t}place_t,company_t");
+ QueryResponse rsp = query(params);
+
+ assertNullFacetTypeInsidePivot(FacetParams.FACET_QUERY, rsp.getFacetPivot().get("place_t,company_t"));
+
+ params = params("q", "*:*",
+ "rows", "0",
+ "stats", "true",
+ "facet", "true",
+ "facet.pivot", "{!query=t}place_t,company_t");
+ rsp = query(params);
+ assertNullFacetTypeInsidePivot(FacetParams.FACET_QUERY, rsp.getFacetPivot().get("place_t,company_t"));
+
+ params = params("q", "*:*",
+ "rows", "0",
+ "facet.query", "{!tag=t}price_ti:[25 TO 100]",
+ "hang", "", // empty
+ "facet", "true",
+ "facet.pivot", "{!query=$hang}place_t,company_t");
+ rsp = query(params);
+ assertNullFacetTypeInsidePivot(FacetParams.FACET_QUERY, rsp.getFacetPivot().get("place_t,company_t"));
+
+ params = params("q", "*:*",
+ "rows", "0",
+ "facet.query", "{!tag=t}price_ti:[25 TO 100]",
+ "hang", "price_ti:[0 TO 20]", // with a query
+ "facet", "true",
+ "facet.pivot", "{!query=$hang}place_t,company_t");
+ rsp = query(params);
+ // we aren't going to start calculating facet query unless the query is specified with a 'facet.query' param
+ // hence hanging an arbitrary query shouldn't work
+ assertNullFacetTypeInsidePivot(FacetParams.FACET_QUERY, rsp.getFacetPivot().get("place_t,company_t"));
+ }
+
+ private void testNegativeRangeQuery() throws Exception {
+ SolrParams params = params("q", "*:*",
+ "rows", "0",
+ "stats", "true",
+ "facet.range", "{!tag=s1 key=price}price_ti",
+ "facet", "true",
+ "facet.pivot", "{!range=s}place_t,company_t",
+ "facet.range.start", "0",
+ "facet.range.end", "100",
+ "facet.range.gap", "20");
+ QueryResponse rsp = query(params);
+ assertNullFacetTypeInsidePivot(FacetParams.FACET_RANGE, rsp.getFacetPivot().get("place_t,company_t"));
+
+ params = params("q", "*:*",
+ "rows", "0",
+ "stats", "true",
+ "facet.range", "{!tag=s1 key=price}price_ti",
+ "facet", "true",
+ "hang", "", // empty!
+ "facet.pivot", "{!range=$hang}place_t,company_t",
+ "facet.range.start", "0",
+ "facet.range.end", "100",
+ "facet.range.gap", "20");
+ rsp = query(params);
+ assertNullFacetTypeInsidePivot(FacetParams.FACET_RANGE, rsp.getFacetPivot().get("place_t,company_t"));
+
+ params = params("q", "*:*",
+ "rows", "0",
+ "stats", "true",
+ "facet.range", "{!tag=s1 key=price}price_ti",
+ "facet", "true",
+ "hang", "price_ti",
+ "facet.pivot", "{!range=$hang}place_t,company_t",
+ "facet.range.start", "0",
+ "facet.range.end", "100",
+ "facet.range.gap", "20");
+ rsp = query(params);
+ assertNullFacetTypeInsidePivot(FacetParams.FACET_RANGE, rsp.getFacetPivot().get("place_t,company_t"));
+ }
+
+ private Map<String, Integer> createExpectedQCount(String[] keys, int[] counts) {
+ Map<String, Integer> expectedQCounts = new LinkedHashMap<>();
+ for (int idx = 0; idx < keys.length; idx++) {
+ expectedQCounts.put(keys[idx], counts[idx]);
+ }
+ return expectedQCounts;
+ }
+
+ private void assertNullFacetTypeInsidePivot(String facetType, List<PivotField> pivots) {
+ for (PivotField pivot : pivots) {
+ if (facetType == FacetParams.FACET_QUERY) {
+ assertNull("pivot=" + pivot + " facetType=" + facetType
+ + " should've been null. Found: " + pivot.getFacetQuery(), pivot.getFacetQuery());
+ } else if (facetType == FacetParams.FACET_RANGE) {
+ assertNull("pivot=" + pivot + " facetType=" + facetType
+ + " should've been null. Found: " + pivot.getFacetRanges(), pivot.getFacetRanges());
+ }
+
+ if (pivot.getPivot() != null) {
+ assertNullFacetTypeInsidePivot(facetType, pivot.getPivot());
+ }
+ }
+ }
+
// Useful to check for errors, orders lists and does toString() equality check
private void testOrderedPivotsStringEquality(
List<PivotField> expectedPlacePivots, List<PivotField> placePivots) {
@@ -526,11 +1518,31 @@ public class DistributedFacetPivotSmallT
assertEquals(msg + " stats max", val, stats.getMax());
}
+ private List<RangeFacet> createExpectedRange(String key, int start, int end,
+ int gap, int... values) {
+ List<RangeFacet> expectedRanges = new ArrayList<>();
+ RangeFacet expectedPrices = new RangeFacet.Numeric(key, start, end, gap, null, null, null);
+ expectedRanges.add(expectedPrices);
+ int idx = 0;
+ for (int range = start; range < end; range += gap) {
+ expectedPrices.addCount(String.valueOf(range), values[idx]);
+ if (idx < values.length) {
+ idx++;
+ }
+ }
+ return expectedRanges;
+ }
+
public static class ComparablePivotField extends PivotField {
-
- public ComparablePivotField(String f, Object v, int count, List<PivotField> pivot) {
- super(f,v,count,pivot, null);
+ public ComparablePivotField(String f, Object v, int count,
+ List<PivotField> pivot, Map<String,Integer> queryCounts, List<RangeFacet> ranges) {
+ super(f, v, count, pivot, null, queryCounts, ranges);
+ }
+
+ public ComparablePivotField(String f, Object v, int count,
+ List<PivotField> pivot) {
+ super(f, v, count, pivot, null, null, null);
}
@Override
@@ -549,6 +1561,44 @@ public class DistributedFacetPivotSmallT
if (getValue() == null) {
if (other.getValue() != null) return false;
} else if (!getValue().equals(other.getValue())) return false;
+ if (getFacetRanges() == null) {
+ if (other.getFacetRanges() != null) return false;
+ } else {
+ if (getFacetRanges().size() != other.getFacetRanges().size()) return false;
+ for (RangeFacet entry : getFacetRanges()) {
+ boolean found = false;
+ for (RangeFacet otherRange : other.getFacetRanges()) {
+ if (otherRange.getName().equals(entry.getName())) {
+ found = true;
+
+ if (!entry.getGap().equals(otherRange.getGap())) return false;
+ if (!entry.getStart().equals(otherRange.getStart())) return false;
+ if (!entry.getEnd().equals(otherRange.getEnd())) return false;
+
+ List<RangeFacet.Count> myCounts = entry.getCounts();
+ List<RangeFacet.Count> otherRangeCounts = otherRange.getCounts();
+ if ( (myCounts == null && otherRangeCounts != null)
+ || (myCounts != null && otherRangeCounts == null)
+ || (myCounts.size() != otherRangeCounts.size())) return false;
+
+ for (int i=0; i<myCounts.size(); i++) {
+ if (!myCounts.get(i).getValue().equals(otherRangeCounts.get(i).getValue())) return false;
+ if (myCounts.get(i).getCount() != otherRangeCounts.get(i).getCount()) return false;
+ }
+ }
+ }
+ if (!found) return false;
+ }
+ }
+ if (getFacetQuery() == null) {
+ if (other.getFacetQuery() != null) return false;
+ } else {
+ if (getFacetQuery().size() != other.getFacetQuery().size()) return false;
+ for (Map.Entry<String,Integer> entry : getFacetQuery().entrySet()) {
+ Integer otherQCount = other.getFacetQuery().get(entry.getKey());
+ if (otherQCount == null || otherQCount != entry.getValue()) return false;
+ }
+ }
return true;
}
}
@@ -564,7 +1614,7 @@ public class DistributedFacetPivotSmallT
equal = true;
for (Object objectInOtherList : otherList) {
if (!contains(objectInOtherList)) {
- equal = false;
+ return false;
}
}
}
@@ -582,7 +1632,7 @@ public class DistributedFacetPivotSmallT
}
}
- public class PivotFieldComparator implements Comparator<PivotField> {
+ public static class PivotFieldComparator implements Comparator<PivotField> {
@Override
public int compare(PivotField o1, PivotField o2) {
@@ -591,6 +1641,33 @@ public class DistributedFacetPivotSmallT
if (compare == 0) {
compare = ((String) o2.getValue()).compareTo((String) o1.getValue());
}
+ if (compare == 0) {
+ for (Map.Entry<String,Integer> entry : o1.getFacetQuery().entrySet()) {
+ compare = entry.getValue().compareTo(
+ o2.getFacetQuery().get(entry.getKey()));
+ if (compare != 0) {
+ break;
+ }
+ }
+ if (compare == 0) {
+ compare = Integer.valueOf(o1.getFacetQuery().size()).compareTo(
+ o2.getFacetQuery().size());
+ }
+ }
+ if (compare == 0) {
+ for (RangeFacet entry : o1.getFacetRanges()) {
+ boolean found = false;
+ for (RangeFacet otherRangeFacet : o2.getFacetRanges()) {
+ if (otherRangeFacet.getName().equals(entry.getName())) {
+ found = true;
+ }
+ }
+ if (!found) {
+ compare = 1;
+ break;
+ }
+ }
+ }
return compare;
}
Modified: lucene/dev/branches/branch_5x/solr/solrj/src/java/org/apache/solr/client/solrj/response/PivotField.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/solrj/src/java/org/apache/solr/client/solrj/response/PivotField.java?rev=1689839&r1=1689838&r2=1689839&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/solrj/src/java/org/apache/solr/client/solrj/response/PivotField.java (original)
+++ lucene/dev/branches/branch_5x/solr/solrj/src/java/org/apache/solr/client/solrj/response/PivotField.java Wed Jul 8 11:05:27 2015
@@ -22,6 +22,8 @@ import java.io.Serializable;
import java.util.List;
import java.util.Map;
+import org.apache.solr.common.util.NamedList;
+
public class PivotField implements Serializable
{
final String _field;
@@ -29,22 +31,26 @@ public class PivotField implements Seria
final int _count;
final List<PivotField> _pivot;
final Map<String,FieldStatsInfo> _statsInfo;
+ final Map<String,Integer> _querycounts;
+ final List<RangeFacet> _ranges;
/**
- * @deprecated Use {@link #PivotField(String,Object,int,List,Map)} with a null <code>statsInfo</code>
+ * @deprecated Use {@link #PivotField(String,Object,int,List,Map,Map,List)} with null <code>statsInfo</code>, queryCounts and ranges
*/
@Deprecated
public PivotField( String f, Object v, int count, List<PivotField> pivot) {
- this(f, v, count, pivot, null);
+ this(f, v, count, pivot, null, null, null);
}
- public PivotField( String f, Object v, int count, List<PivotField> pivot, Map<String,FieldStatsInfo> statsInfo)
+ public PivotField( String f, Object v, int count, List<PivotField> pivot, Map<String,FieldStatsInfo> statsInfo, Map<String,Integer> queryCounts, List<RangeFacet> ranges)
{
_field = f;
_value = v;
_count = count;
_pivot = pivot;
_statsInfo = statsInfo;
+ _querycounts= queryCounts;
+ _ranges= ranges;
}
public String getField() {
@@ -67,6 +73,14 @@ public class PivotField implements Seria
return _statsInfo;
}
+ public Map<String,Integer> getFacetQuery() {
+ return _querycounts;
+ }
+
+ public List<RangeFacet> getFacetRanges() {
+ return _ranges;
+ }
+
@Override
public String toString()
{
@@ -88,6 +102,12 @@ public class PivotField implements Seria
out.print("]");
}
out.println();
+ if(_querycounts != null) {
+ out.println(_querycounts.toString());
+ }
+ if(_ranges != null) {
+ out.println(_ranges.toString());
+ }
if( _pivot != null ) {
for( PivotField p : _pivot ) {
p.write( out, indent+1 );
Modified: lucene/dev/branches/branch_5x/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java?rev=1689839&r1=1689838&r2=1689839&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java (original)
+++ lucene/dev/branches/branch_5x/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java Wed Jul 8 11:05:27 2015
@@ -348,41 +348,7 @@ public class QueryResponse extends SolrR
//Parse range facets
NamedList<NamedList<Object>> rf = (NamedList<NamedList<Object>>) info.get("facet_ranges");
if (rf != null) {
- _facetRanges = new ArrayList<>( rf.size() );
- for (Map.Entry<String, NamedList<Object>> facet : rf) {
- NamedList<Object> values = facet.getValue();
- Object rawGap = values.get("gap");
-
- RangeFacet rangeFacet;
- if (rawGap instanceof Number) {
- Number gap = (Number) rawGap;
- Number start = (Number) values.get("start");
- Number end = (Number) values.get("end");
-
- Number before = (Number) values.get("before");
- Number after = (Number) values.get("after");
- Number between = (Number) values.get("between");
-
- rangeFacet = new RangeFacet.Numeric(facet.getKey(), start, end, gap, before, after, between);
- } else {
- String gap = (String) rawGap;
- Date start = (Date) values.get("start");
- Date end = (Date) values.get("end");
-
- Number before = (Number) values.get("before");
- Number after = (Number) values.get("after");
- Number between = (Number) values.get("between");
-
- rangeFacet = new RangeFacet.Date(facet.getKey(), start, end, gap, before, after, between);
- }
-
- NamedList<Integer> counts = (NamedList<Integer>) values.get("counts");
- for (Map.Entry<String, Integer> entry : counts) {
- rangeFacet.addCount(entry.getKey(), entry.getValue());
- }
-
- _facetRanges.add(rangeFacet);
- }
+ _facetRanges = extractRangeFacets(rf);
}
//Parse pivot facets
@@ -408,7 +374,47 @@ public class QueryResponse extends SolrR
}
}
}
-
+
+ private List<RangeFacet> extractRangeFacets(NamedList<NamedList<Object>> rf) {
+ List<RangeFacet> facetRanges = new ArrayList<>( rf.size() );
+
+ for (Map.Entry<String, NamedList<Object>> facet : rf) {
+ NamedList<Object> values = facet.getValue();
+ Object rawGap = values.get("gap");
+
+ RangeFacet rangeFacet;
+ if (rawGap instanceof Number) {
+ Number gap = (Number) rawGap;
+ Number start = (Number) values.get("start");
+ Number end = (Number) values.get("end");
+
+ Number before = (Number) values.get("before");
+ Number after = (Number) values.get("after");
+ Number between = (Number) values.get("between");
+
+ rangeFacet = new RangeFacet.Numeric(facet.getKey(), start, end, gap, before, after, between);
+ } else {
+ String gap = (String) rawGap;
+ Date start = (Date) values.get("start");
+ Date end = (Date) values.get("end");
+
+ Number before = (Number) values.get("before");
+ Number after = (Number) values.get("after");
+ Number between = (Number) values.get("between");
+
+ rangeFacet = new RangeFacet.Date(facet.getKey(), start, end, gap, before, after, between);
+ }
+
+ NamedList<Integer> counts = (NamedList<Integer>) values.get("counts");
+ for (Map.Entry<String, Integer> entry : counts) {
+ rangeFacet.addCount(entry.getKey(), entry.getValue());
+ }
+
+ facetRanges.add(rangeFacet);
+ }
+ return facetRanges;
+ }
+
protected List<PivotField> readPivots( List<NamedList> list )
{
ArrayList<PivotField> values = new ArrayList<>( list.size() );
@@ -423,6 +429,8 @@ public class QueryResponse extends SolrR
List<PivotField> subPivots = null;
Map<String,FieldStatsInfo> fieldStatsInfos = null;
+ Map<String,Integer> queryCounts = null;
+ List<RangeFacet> ranges = null;
if (4 <= nl.size()) {
for(int index = 3; index < nl.size(); index++) {
@@ -444,6 +452,21 @@ public class QueryResponse extends SolrR
fieldStatsInfos = extractFieldStatsInfo((NamedList<Object>) val);
break;
}
+ case "queries": {
+ // Parse the queries
+ queryCounts = new LinkedHashMap<>();
+ NamedList<Integer> fq = (NamedList<Integer>) val;
+ if (fq != null) {
+ for( Map.Entry<String, Integer> entry : fq ) {
+ queryCounts.put( entry.getKey(), entry.getValue() );
+ }
+ }
+ break;
+ }
+ case "ranges": {
+ ranges = extractRangeFacets((NamedList<NamedList<Object>>) val);
+ break;
+ }
default:
throw new RuntimeException( "unknown key in pivot: "+ key+ " ["+val+"]");
@@ -451,7 +474,7 @@ public class QueryResponse extends SolrR
}
}
- values.add( new PivotField( f, v, cnt, subPivots, fieldStatsInfos ) );
+ values.add( new PivotField( f, v, cnt, subPivots, fieldStatsInfos, queryCounts, ranges ) );
}
return values;
}
Modified: lucene/dev/branches/branch_5x/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java?rev=1689839&r1=1689838&r2=1689839&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java (original)
+++ lucene/dev/branches/branch_5x/solr/solrj/src/test/org/apache/solr/client/solrj/SolrExampleTests.java Wed Jul 8 11:05:27 2015
@@ -42,7 +42,9 @@ import org.apache.solr.client.solrj.resp
import org.apache.solr.client.solrj.response.LukeResponse;
import org.apache.solr.client.solrj.response.PivotField;
import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.client.solrj.response.RangeFacet;
import org.apache.solr.client.solrj.response.UpdateResponse;
+import org.apache.solr.client.solrj.response.RangeFacet.Count;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrException;
@@ -65,6 +67,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Random;
@@ -1094,6 +1097,218 @@ abstract public class SolrExampleTests e
}
+ @Test
+ public void testPivotFacetsQueries() throws Exception {
+ SolrClient client = getSolrClient();
+
+ // Empty the database...
+ client.deleteByQuery("*:*");// delete everything!
+ client.commit();
+ assertNumFound("*:*", 0); // make sure it got in
+
+ int id = 1;
+ ArrayList<SolrInputDocument> docs = new ArrayList<>();
+ docs.add(makeTestDoc("id", id++, "features", "aaa", "cat", "a", "inStock", true, "popularity", 12, "price", .017));
+ docs.add(makeTestDoc("id", id++, "features", "aaa", "cat", "a", "inStock", false, "popularity", 13, "price", 16.04));
+ docs.add(makeTestDoc("id", id++, "features", "aaa", "cat", "a", "inStock", true, "popularity", 14, "price", 12.34));
+ docs.add(makeTestDoc("id", id++, "features", "aaa", "cat", "b", "inStock", false, "popularity", 24, "price", 51.39));
+ docs.add(makeTestDoc("id", id++, "features", "aaa", "cat", "b", "inStock", true, "popularity", 28, "price", 131.39));
+ docs.add(makeTestDoc("id", id++, "features", "bbb", "cat", "a", "inStock", false, "popularity", 32));
+ docs.add(makeTestDoc("id", id++, "features", "bbb", "cat", "a", "inStock", true, "popularity", 31, "price", 131.39));
+ docs.add(makeTestDoc("id", id++, "features", "bbb", "cat", "b", "inStock", false, "popularity", 36));
+ docs.add(makeTestDoc("id", id++, "features", "bbb", "cat", "b", "inStock", true, "popularity", 37, "price", 1.39));
+ docs.add(makeTestDoc("id", id++, "features", "bbb", "cat", "b", "inStock", false, "popularity", 38, "price", 47.98));
+ docs.add(makeTestDoc("id", id++, "features", "bbb", "cat", "b", "inStock", true, "popularity", -38));
+ docs.add(makeTestDoc("id", id++, "cat", "b")); // something not matching all fields
+ client.add(docs);
+ client.commit();
+
+ SolrQuery query = new SolrQuery("*:*");
+ query.addFacetPivotField("{!query=s1}features,manu");
+ query.addFacetQuery("{!key=highPrice tag=s1}price:[100 TO *]");
+ query.addFacetQuery("{!tag=s1 key=lowPrice}price:[0 TO 50]");
+ query.setFacetMinCount(0);
+ query.setRows(0);
+ QueryResponse rsp = client.query(query);
+
+ Map<String,Integer> map = rsp.getFacetQuery();
+ assertEquals(2, map.get("highPrice").intValue());
+ assertEquals(5, map.get("lowPrice").intValue());
+
+ NamedList<List<PivotField>> pivots = rsp.getFacetPivot();
+ List<PivotField> pivotValues = pivots.get("features,manu");
+
+ PivotField featuresBBBPivot = pivotValues.get(0);
+ assertEquals("features", featuresBBBPivot.getField());
+ assertEquals("bbb", featuresBBBPivot.getValue());
+ assertNotNull(featuresBBBPivot.getFacetQuery());
+ assertEquals(2, featuresBBBPivot.getFacetQuery().size());
+ assertEquals(1, featuresBBBPivot.getFacetQuery().get("highPrice").intValue());
+ assertEquals(2, featuresBBBPivot.getFacetQuery().get("lowPrice").intValue());
+
+ PivotField featuresAAAPivot = pivotValues.get(1);
+ assertEquals("features", featuresAAAPivot.getField());
+ assertEquals("aaa", featuresAAAPivot.getValue());
+ assertNotNull(featuresAAAPivot.getFacetQuery());
+ assertEquals(2, featuresAAAPivot.getFacetQuery().size());
+ assertEquals(1, featuresAAAPivot.getFacetQuery().get("highPrice").intValue());
+ assertEquals(3, featuresAAAPivot.getFacetQuery().get("lowPrice").intValue());
+ }
+
+ @Test
+ public void testPivotFacetsRanges() throws Exception {
+ SolrClient client = getSolrClient();
+
+ // Empty the database...
+ client.deleteByQuery("*:*");// delete everything!
+ client.commit();
+ assertNumFound("*:*", 0); // make sure it got in
+
+ int id = 1;
+ ArrayList<SolrInputDocument> docs = new ArrayList<>();
+ docs.add(makeTestDoc("id", id++, "features", "aaa", "cat", "a", "inStock", true, "popularity", 12, "price", .017));
+ docs.add(makeTestDoc("id", id++, "features", "aaa", "cat", "a", "inStock", false, "popularity", 13, "price", 16.04));
+ docs.add(makeTestDoc("id", id++, "features", "aaa", "cat", "a", "inStock", true, "popularity", 14, "price", 12.34));
+ docs.add(makeTestDoc("id", id++, "features", "aaa", "cat", "b", "inStock", false, "popularity", 24, "price", 51.39));
+ docs.add(makeTestDoc("id", id++, "features", "aaa", "cat", "b", "inStock", true, "popularity", 28, "price", 131.39));
+ docs.add(makeTestDoc("id", id++, "features", "bbb", "cat", "a", "inStock", false, "popularity", 32));
+ docs.add(makeTestDoc("id", id++, "features", "bbb", "cat", "a", "inStock", true, "popularity", 31, "price", 131.39));
+ docs.add(makeTestDoc("id", id++, "features", "bbb", "cat", "b", "inStock", false, "popularity", 36));
+ docs.add(makeTestDoc("id", id++, "features", "bbb", "cat", "b", "inStock", true, "popularity", 37, "price", 1.39));
+ docs.add(makeTestDoc("id", id++, "features", "bbb", "cat", "b", "inStock", false, "popularity", 38, "price", 47.98));
+ docs.add(makeTestDoc("id", id++, "features", "bbb", "cat", "b", "inStock", true, "popularity", -38));
+ docs.add(makeTestDoc("id", id++, "cat", "b")); // something not matching all fields
+ client.add(docs);
+ client.commit();
+
+ SolrQuery query = new SolrQuery("*:*");
+ query.addFacetPivotField("{!range=s1}features,manu");
+ query.add(FacetParams.FACET_RANGE, "{!key=price1 tag=s1}price");
+ query.add(String.format(Locale.ROOT, "f.%s.%s", "price", FacetParams.FACET_RANGE_START), "0");
+ query.add(String.format(Locale.ROOT, "f.%s.%s", "price", FacetParams.FACET_RANGE_END), "200");
+ query.add(String.format(Locale.ROOT, "f.%s.%s", "price", FacetParams.FACET_RANGE_GAP), "50");
+ query.set(FacetParams.FACET, true);
+ query.add(FacetParams.FACET_RANGE, "{!key=price2 tag=s1}price");
+ query.setFacetMinCount(0);
+ query.setRows(0);
+ QueryResponse rsp = client.query(query);
+
+ List<RangeFacet> list = rsp.getFacetRanges();
+ assertEquals(2, list.size());
+ @SuppressWarnings("unchecked")
+ RangeFacet<Float, Float> range1 = list.get(0);
+ assertEquals("price1", range1.getName());
+ assertEquals(0, range1.getStart().intValue());
+ assertEquals(200, range1.getEnd().intValue());
+ assertEquals(50, range1.getGap().intValue());
+ List<Count> counts1 = range1.getCounts();
+ assertEquals(4, counts1.size());
+ assertEquals(5, counts1.get(0).getCount());
+ assertEquals("0.0", counts1.get(0).getValue());
+ assertEquals(1, counts1.get(1).getCount());
+ assertEquals("50.0", counts1.get(1).getValue());
+ assertEquals(2, counts1.get(2).getCount());
+ assertEquals("100.0", counts1.get(2).getValue());
+ assertEquals(0, counts1.get(3).getCount());
+ assertEquals("150.0", counts1.get(3).getValue());
+ @SuppressWarnings("unchecked")
+ RangeFacet<Float, Float> range2 = list.get(1);
+ assertEquals("price2", range2.getName());
+ assertEquals(0, range2.getStart().intValue());
+ assertEquals(200, range2.getEnd().intValue());
+ assertEquals(50, range2.getGap().intValue());
+ List<Count> counts2 = range2.getCounts();
+ assertEquals(4, counts2.size());
+ assertEquals(5, counts2.get(0).getCount());
+ assertEquals("0.0", counts2.get(0).getValue());
+ assertEquals(1, counts2.get(1).getCount());
+ assertEquals("50.0", counts2.get(1).getValue());
+ assertEquals(2, counts2.get(2).getCount());
+ assertEquals("100.0", counts2.get(2).getValue());
+ assertEquals(0, counts2.get(3).getCount());
+ assertEquals("150.0", counts2.get(3).getValue());
+
+ NamedList<List<PivotField>> pivots = rsp.getFacetPivot();
+ List<PivotField> pivotValues = pivots.get("features,manu");
+
+ PivotField featuresBBBPivot = pivotValues.get(0);
+ assertEquals("features", featuresBBBPivot.getField());
+ assertEquals("bbb", featuresBBBPivot.getValue());
+ List<RangeFacet> featuresBBBRanges = featuresBBBPivot.getFacetRanges();
+
+ for (RangeFacet range : featuresBBBRanges) {
+ if (range.getName().equals("price1")) {
+ assertNotNull(range);
+ assertEquals(0, ((Float)range.getStart()).intValue());
+ assertEquals(200, ((Float)range.getEnd()).intValue());
+ assertEquals(50, ((Float)range.getGap()).intValue());
+ List<Count> counts = range.getCounts();
+ assertEquals(4, counts.size());
+ for (Count count : counts) {
+ switch (count.getValue()) {
+ case "0.0": assertEquals(2, count.getCount()); break;
+ case "50.0": assertEquals(0, count.getCount()); break;
+ case "100.0": assertEquals(1, count.getCount()); break;
+ case "150.0": assertEquals(0, count.getCount()); break;
+ }
+ }
+ } else if (range.getName().equals("price2")) {
+ assertNotNull(range);
+ assertEquals(0, ((Float) range.getStart()).intValue());
+ assertEquals(200, ((Float) range.getEnd()).intValue());
+ assertEquals(50, ((Float) range.getGap()).intValue());
+ List<Count> counts = range.getCounts();
+ assertEquals(4, counts.size());
+ for (Count count : counts) {
+ switch (count.getValue()) {
+ case "0.0": assertEquals(2, count.getCount()); break;
+ case "50.0": assertEquals(0, count.getCount()); break;
+ case "100.0": assertEquals(1, count.getCount()); break;
+ case "150.0": assertEquals(0, count.getCount()); break;
+ }
+ }
+ }
+ }
+
+ PivotField featuresAAAPivot = pivotValues.get(1);
+ assertEquals("features", featuresAAAPivot.getField());
+ assertEquals("aaa", featuresAAAPivot.getValue());
+ List<RangeFacet> facetRanges = featuresAAAPivot.getFacetRanges();
+ for (RangeFacet range : facetRanges) {
+ if (range.getName().equals("price1")) {
+ assertNotNull(range);
+ assertEquals(0, ((Float)range.getStart()).intValue());
+ assertEquals(200, ((Float)range.getEnd()).intValue());
+ assertEquals(50, ((Float)range.getGap()).intValue());
+ List<Count> counts = range.getCounts();
+ assertEquals(4, counts.size());
+ for (Count count : counts) {
+ switch (count.getValue()) {
+ case "0.0": assertEquals(3, count.getCount()); break;
+ case "50.0": assertEquals(1, count.getCount()); break;
+ case "100.0": assertEquals(1, count.getCount()); break;
+ case "150.0": assertEquals(0, count.getCount()); break;
+ }
+ }
+ } else if (range.getName().equals("price2")) {
+ assertNotNull(range);
+ assertEquals(0, ((Float)range.getStart()).intValue());
+ assertEquals(200, ((Float)range.getEnd()).intValue());
+ assertEquals(50, ((Float)range.getGap()).intValue());
+ List<Count> counts = range.getCounts();
+ assertEquals(4, counts.size());
+ for (Count count : counts) {
+ switch (count.getValue()) {
+ case "0.0": assertEquals(3, count.getCount()); break;
+ case "50.0": assertEquals(1, count.getCount()); break;
+ case "100.0": assertEquals(1, count.getCount()); break;
+ case "150.0": assertEquals(0, count.getCount()); break;
+ }
+ }
+ }
+ }
+ }
+
public void testPivotFacetsMissing() throws Exception {
doPivotFacetTest(true);
}
@@ -1870,4 +2085,4 @@ abstract public class SolrExampleTests e
}
return sdoc;
}
-}
\ No newline at end of file
+}