You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by da...@apache.org on 2018/11/20 15:16:28 UTC

[18/31] lucene-solr:jira/http2: SOLR-12981: Introduce SolrJ type for JSON facet response parsing

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/d17c6d88/solr/solrj/src/test/org/apache/solr/client/solrj/request/json/JsonQueryRequestFacetingIntegrationTest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/request/json/JsonQueryRequestFacetingIntegrationTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/request/json/JsonQueryRequestFacetingIntegrationTest.java
index 7717f7f..344fdd2 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/request/json/JsonQueryRequestFacetingIntegrationTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/request/json/JsonQueryRequestFacetingIntegrationTest.java
@@ -19,7 +19,9 @@ package org.apache.solr.client.solrj.request.json;
 
 import java.io.File;
 import java.io.IOException;
+import java.time.Instant;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -27,12 +29,13 @@ import java.util.Map;
 import org.apache.solr.client.solrj.request.AbstractUpdateRequest;
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.client.solrj.request.ContentStreamUpdateRequest;
+import org.apache.solr.client.solrj.response.json.BucketJsonFacet;
+import org.apache.solr.client.solrj.response.json.NestableJsonFacet;
 import org.apache.solr.client.solrj.response.QueryResponse;
 import org.apache.solr.client.solrj.response.UpdateResponse;
 import org.apache.solr.cloud.SolrCloudTestCase;
 import org.apache.solr.common.MapWriter;
 import org.apache.solr.common.SolrDocumentList;
-import org.apache.solr.common.util.NamedList;
 import org.apache.solr.util.ExternalPaths;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -43,6 +46,7 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
   private static final String CONFIG_NAME = "techproducts_config";
   private static final int NUM_TECHPRODUCTS_DOCS = 32;
   private static final int NUM_IN_STOCK = 17;
+  private static final int NUM_CATEGORIES = 16;
   private static final int NUM_ELECTRONICS = 12;
   private static final int NUM_CURRENCY = 4;
   private static final int NUM_MEMORY = 3;
@@ -79,15 +83,53 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
 
     QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
 
-    assertEquals(0, response.getStatus());
-    final SolrDocumentList returnedDocs = response.getResults();
-    assertEquals(NUM_TECHPRODUCTS_DOCS, returnedDocs.getNumFound());
-    assertEquals(10, returnedDocs.size());
-    final NamedList<Object> rawResponse = response.getResponse();
-    assertHasFacetWithBucketValues(rawResponse,"top_cats",
-        new FacetBucket("electronics",NUM_ELECTRONICS),
+    assertExpectedDocumentsFoundAndReturned(response, NUM_TECHPRODUCTS_DOCS, 10);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
+    assertEquals(NUM_TECHPRODUCTS_DOCS, topLevelFacetData.getCount());
+    assertHasFacetWithBucketValues(topLevelFacetData, "top_cats",
+        new FacetBucket("electronics", NUM_ELECTRONICS),
+        new FacetBucket("currency", NUM_CURRENCY),
+        new FacetBucket("memory", NUM_MEMORY));
+  }
+
+  @Test
+  public void testTermsFacetWithNumBucketsRequested() throws Exception {
+    final TermsFacetMap categoriesFacetMap = new TermsFacetMap("cat")
+        .includeTotalNumBuckets(true)
+        .setLimit(3);
+    final JsonQueryRequest request = new JsonQueryRequest()
+        .setQuery("*:*")
+        .withFacet("top_cats", categoriesFacetMap);
+
+    QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
+
+    assertEquals(NUM_TECHPRODUCTS_DOCS, topLevelFacetData.getCount());
+    assertHasFacetWithBucketValues(topLevelFacetData, "top_cats",
+        new FacetBucket("electronics", NUM_ELECTRONICS),
+        new FacetBucket("currency", NUM_CURRENCY),
+        new FacetBucket("memory", NUM_MEMORY));
+    assertEquals(NUM_CATEGORIES, topLevelFacetData.getBucketBasedFacets("top_cats").getNumBuckets());
+  }
+
+  @Test
+  public void testTermsFacetWithAllBucketsRequested() throws Exception {
+    final TermsFacetMap categoriesFacetMap = new TermsFacetMap("cat")
+        .includeAllBucketsUnionBucket(true)
+        .setLimit(3);
+    final JsonQueryRequest request = new JsonQueryRequest()
+        .setQuery("*:*")
+        .withFacet("top_cats", categoriesFacetMap);
+
+    QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
+
+    assertEquals(NUM_TECHPRODUCTS_DOCS, topLevelFacetData.getCount());
+    assertHasFacetWithBucketValues(topLevelFacetData, "top_cats",
+        new FacetBucket("electronics", NUM_ELECTRONICS),
         new FacetBucket("currency", NUM_CURRENCY),
         new FacetBucket("memory", NUM_MEMORY));
+    assertEquals(37, topLevelFacetData.getBucketBasedFacets("top_cats").getAllBuckets());
   }
 
   @Test
@@ -106,13 +148,11 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
 
     QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
 
-    assertEquals(0, response.getStatus());
-    final SolrDocumentList returnedDocs = response.getResults();
-    assertEquals(NUM_TECHPRODUCTS_DOCS, returnedDocs.getNumFound());
-    assertEquals(10, returnedDocs.size());
-    final NamedList<Object> rawResponse = response.getResponse();
-    assertHasFacetWithBucketValues(rawResponse,"top_cats",
-        new FacetBucket("electronics",NUM_ELECTRONICS),
+    assertExpectedDocumentsFoundAndReturned(response, NUM_TECHPRODUCTS_DOCS, 10);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
+    assertEquals(NUM_TECHPRODUCTS_DOCS, topLevelFacetData.getCount());
+    assertHasFacetWithBucketValues(topLevelFacetData, "top_cats",
+        new FacetBucket("electronics", NUM_ELECTRONICS),
         new FacetBucket("currency", NUM_CURRENCY),
         new FacetBucket("memory", NUM_MEMORY));
   }
@@ -130,17 +170,15 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
 
     QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
 
-    assertEquals(0, response.getStatus());
-    final SolrDocumentList returnedDocs = response.getResults();
-    assertEquals(NUM_TECHPRODUCTS_DOCS, returnedDocs.getNumFound());
-    assertEquals(10, returnedDocs.size());
-    final NamedList<Object> rawResponse = response.getResponse();
-    assertHasFacetWithBucketValues(rawResponse,"top_cats",
-        new FacetBucket("electronics",NUM_ELECTRONICS),
+    assertExpectedDocumentsFoundAndReturned(response, NUM_TECHPRODUCTS_DOCS, 10);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
+    assertEquals(NUM_TECHPRODUCTS_DOCS, topLevelFacetData.getCount());
+    assertHasFacetWithBucketValues(topLevelFacetData, "top_cats",
+        new FacetBucket("electronics", NUM_ELECTRONICS),
         new FacetBucket("currency", NUM_CURRENCY),
         new FacetBucket("memory", NUM_MEMORY));
-    assertHasFacetWithBucketValues(rawResponse,"top_manufacturers",
-        new FacetBucket("corsair",NUM_CORSAIR),
+    assertHasFacetWithBucketValues(topLevelFacetData, "top_manufacturers",
+        new FacetBucket("corsair", NUM_CORSAIR),
         new FacetBucket("belkin", NUM_BELKIN),
         new FacetBucket("canon", NUM_CANON));
   }
@@ -154,12 +192,10 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
 
     QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
 
-    assertEquals(0, response.getStatus());
-    final SolrDocumentList returnedDocs = response.getResults();
-    assertEquals(NUM_TECHPRODUCTS_DOCS, returnedDocs.getNumFound());
-    assertEquals(10, returnedDocs.size());
-    final NamedList<Object> rawResponse = response.getResponse();
-    assertHasFacetWithBucketValues(rawResponse,"prices",
+    assertExpectedDocumentsFoundAndReturned(response, NUM_TECHPRODUCTS_DOCS, 10);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
+    assertEquals(NUM_TECHPRODUCTS_DOCS, topLevelFacetData.getCount());
+    assertHasFacetWithBucketValues(topLevelFacetData,"prices",
         new FacetBucket(0.0f, 5),
         new FacetBucket(20.0f, 0),
         new FacetBucket(40.0f, 0),
@@ -168,6 +204,27 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
   }
 
   @Test
+  public void testSingleDateRangeFacet() throws Exception {
+    final Date startDate = new Date(Instant.parse("2005-08-01T16:30:25Z").toEpochMilli());
+    final Date endDate = new Date(Instant.parse("2006-02-13T15:26:37Z").toEpochMilli());
+    final RangeFacetMap manufactureDateFacet = new RangeFacetMap("manufacturedate_dt", startDate, endDate, "+1MONTH")
+        .setMinCount(1);
+    final JsonQueryRequest request = new JsonQueryRequest()
+        .setQuery("*:*")
+        .withFacet("man_date", manufactureDateFacet);
+
+    QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
+
+    assertExpectedDocumentsFoundAndReturned(response, NUM_TECHPRODUCTS_DOCS, 10);
+    assertEquals(NUM_TECHPRODUCTS_DOCS, topLevelFacetData.getCount());
+    assertHasFacetWithBucketValues(topLevelFacetData,"man_date",
+        new FacetBucket(new Date(Instant.parse("2005-08-01T16:30:25Z").toEpochMilli()), 1),
+        new FacetBucket(new Date(Instant.parse("2005-10-01T16:30:25Z").toEpochMilli()), 1),
+        new FacetBucket(new Date(Instant.parse("2006-02-01T16:30:25Z").toEpochMilli()), 9));
+  }
+
+  @Test
   public void testMultiRangeFacet() throws Exception {
     final RangeFacetMap pricesFacet = new RangeFacetMap("price", 0, 100, 20);
     final RangeFacetMap shippingWeightFacet = new RangeFacetMap("weight", 0, 200, 50);
@@ -178,18 +235,16 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
 
     QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
 
-    assertEquals(0, response.getStatus());
-    final SolrDocumentList returnedDocs = response.getResults();
-    assertEquals(NUM_TECHPRODUCTS_DOCS, returnedDocs.getNumFound());
-    assertEquals(10, returnedDocs.size());
-    final NamedList<Object> rawResponse = response.getResponse();
-    assertHasFacetWithBucketValues(rawResponse,"prices",
+    assertExpectedDocumentsFoundAndReturned(response, NUM_TECHPRODUCTS_DOCS, 10);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
+    assertEquals(NUM_TECHPRODUCTS_DOCS, topLevelFacetData.getCount());
+    assertHasFacetWithBucketValues(topLevelFacetData,"prices",
         new FacetBucket(0.0f, 5),
         new FacetBucket(20.0f, 0),
         new FacetBucket(40.0f, 0),
         new FacetBucket(60.0f, 1),
         new FacetBucket(80.0f, 1));
-    assertHasFacetWithBucketValues(rawResponse, "shipping_weights",
+    assertHasFacetWithBucketValues(topLevelFacetData, "shipping_weights",
         new FacetBucket(0.0f, 6),
         new FacetBucket(50.0f, 0),
         new FacetBucket(100.0f, 0),
@@ -204,12 +259,10 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
 
     QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
 
-    assertEquals(0, response.getStatus());
-    final SolrDocumentList returnedDocs = response.getResults();
-    assertEquals(NUM_TECHPRODUCTS_DOCS, returnedDocs.getNumFound());
-    assertEquals(10, returnedDocs.size());
-    final NamedList<Object> rawResponse = response.getResponse();
-    assertHasStatFacetWithValue(rawResponse,"sum_price", 5251.270030975342);
+    assertExpectedDocumentsFoundAndReturned(response, NUM_TECHPRODUCTS_DOCS, 10);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
+    assertEquals(NUM_TECHPRODUCTS_DOCS, topLevelFacetData.getCount());
+    assertHasStatFacetWithValue(topLevelFacetData,"sum_price", 5251.270030975342);
   }
 
   @Test
@@ -221,13 +274,10 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
 
     QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
 
-    assertEquals(0, response.getStatus());
-    final SolrDocumentList returnedDocs = response.getResults();
-    assertEquals(NUM_TECHPRODUCTS_DOCS, returnedDocs.getNumFound());
-    assertEquals(10, returnedDocs.size());
-    final NamedList<Object> rawResponse = response.getResponse();
-    assertHasStatFacetWithValue(rawResponse,"sum_price", 5251.270030975342);
-    assertHasStatFacetWithValue(rawResponse,"avg_price", 328.20437693595886);
+    assertExpectedDocumentsFoundAndReturned(response, NUM_TECHPRODUCTS_DOCS, 10);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
+    assertHasStatFacetWithValue(topLevelFacetData,"sum_price", 5251.270030975342);
+    assertHasStatFacetWithValue(topLevelFacetData,"avg_price", 328.20437693595886);
   }
 
   @Test
@@ -241,14 +291,13 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
 
     QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
 
-    assertEquals(0, response.getStatus());
-    final SolrDocumentList returnedDocs = response.getResults();
-    assertEquals(NUM_TECHPRODUCTS_DOCS, returnedDocs.getNumFound());
-    assertEquals(10, returnedDocs.size());
-    final NamedList<Object> rawResponse = response.getResponse();
-    assertHasStatFacetWithValue(rawResponse,"avg_price", 328.20437693595886);
-    assertHasFacetWithBucketValues(rawResponse,"top_cats", new FacetBucket("electronics",NUM_ELECTRONICS),
-        new FacetBucket("currency", NUM_CURRENCY), new FacetBucket("memory", NUM_MEMORY));
+    assertExpectedDocumentsFoundAndReturned(response, NUM_TECHPRODUCTS_DOCS, 10);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
+    assertHasStatFacetWithValue(topLevelFacetData,"avg_price", 328.20437693595886);
+    assertHasFacetWithBucketValues(topLevelFacetData,"top_cats",
+        new FacetBucket("electronics",NUM_ELECTRONICS),
+        new FacetBucket("currency", NUM_CURRENCY),
+        new FacetBucket("memory", NUM_MEMORY));
   }
 
   @Test
@@ -262,22 +311,21 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
 
     QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
 
-    assertEquals(0, response.getStatus());
-    final SolrDocumentList returnedDocs = response.getResults();
-    assertEquals(NUM_TECHPRODUCTS_DOCS, returnedDocs.getNumFound());
-    assertEquals(10, returnedDocs.size());
-    final NamedList<Object> rawResponse = response.getResponse();
+    assertExpectedDocumentsFoundAndReturned(response, NUM_TECHPRODUCTS_DOCS, 10);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
     // Test top level facets
-    assertHasFacetWithBucketValues(rawResponse,"top_cats", new FacetBucket("electronics",NUM_ELECTRONICS),
-        new FacetBucket("currency", NUM_CURRENCY), new FacetBucket("memory", NUM_MEMORY));
+    assertHasFacetWithBucketValues(topLevelFacetData,"top_cats",
+        new FacetBucket("electronics",NUM_ELECTRONICS),
+        new FacetBucket("currency", NUM_CURRENCY),
+        new FacetBucket("memory", NUM_MEMORY));
     // Test subfacet values for each top-level facet bucket
-    final List<NamedList<Object>> topLevelFacetResponse = (List<NamedList<Object>>) rawResponse.findRecursive("facets", "top_cats", "buckets");
-    final NamedList<Object> electronicsSubFacet = topLevelFacetResponse.get(0);
-    assertFacetResponseHasFacetWithBuckets(electronicsSubFacet, "top_manufacturers_for_cat", new FacetBucket("corsair", 3));
-    final NamedList<Object> currencySubfacet = topLevelFacetResponse.get(1);
-    assertFacetResponseHasFacetWithBuckets(currencySubfacet, "top_manufacturers_for_cat", new FacetBucket("boa", 1));
-    final NamedList<Object> memorySubfacet = topLevelFacetResponse.get(2);
-    assertFacetResponseHasFacetWithBuckets(memorySubfacet, "top_manufacturers_for_cat", new FacetBucket("corsair", 3));
+    final List<BucketJsonFacet> topCatsBuckets = topLevelFacetData.getBucketBasedFacets("top_cats").getBuckets();
+    final NestableJsonFacet electronicsFacet = topCatsBuckets.get(0);
+    assertHasFacetWithBucketValues(electronicsFacet, "top_manufacturers_for_cat", new FacetBucket("corsair", 3));
+    final NestableJsonFacet currencyFacet = topCatsBuckets.get(1);
+    assertHasFacetWithBucketValues(currencyFacet, "top_manufacturers_for_cat", new FacetBucket("boa", 1));
+    final NestableJsonFacet memoryFacet = topCatsBuckets.get(2);
+    assertHasFacetWithBucketValues(memoryFacet, "top_manufacturers_for_cat", new FacetBucket("corsair", 3));
   }
 
   @Test
@@ -293,22 +341,18 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
 
     QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
 
-    assertEquals(0, response.getStatus());
-    final SolrDocumentList returnedDocs = response.getResults();
-    assertEquals(NUM_TECHPRODUCTS_DOCS, returnedDocs.getNumFound());
-    assertEquals(10, returnedDocs.size());
-    final NamedList<Object> rawResponse = response.getResponse();
+    assertExpectedDocumentsFoundAndReturned(response, NUM_TECHPRODUCTS_DOCS, 10);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
     // Test top level facets
-    assertHasFacetWithBucketValues(rawResponse,"top_cats", new FacetBucket("electronics",NUM_ELECTRONICS),
-        new FacetBucket("currency", NUM_CURRENCY), new FacetBucket("memory", NUM_MEMORY));
+    assertHasFacetWithBucketValues(topLevelFacetData,"top_cats",
+        new FacetBucket("electronics",NUM_ELECTRONICS),
+        new FacetBucket("currency", NUM_CURRENCY),
+        new FacetBucket("memory", NUM_MEMORY));
     // Test subfacet values for each top-level facet bucket
-    final List<NamedList<Object>> topLevelFacetResponse = (List<NamedList<Object>>) rawResponse.findRecursive("facets", "top_cats", "buckets");
-    final NamedList<Object> electronicsSubFacet = topLevelFacetResponse.get(0);
-    assertFacetResponseHasStatFacetWithValue(electronicsSubFacet, subfacetName, 252.02909261530095);
-    final NamedList<Object> currencySubfacet = topLevelFacetResponse.get(1);
-    assertFacetResponseHasStatFacetWithValue(currencySubfacet, subfacetName, 0.0);
-    final NamedList<Object> memorySubfacet = topLevelFacetResponse.get(2);
-    assertFacetResponseHasStatFacetWithValue(memorySubfacet, subfacetName, 129.99499893188477);
+    final List<BucketJsonFacet> topCatsResultBuckets = topLevelFacetData.getBucketBasedFacets("top_cats").getBuckets();
+    assertHasStatFacetWithValue(topCatsResultBuckets.get(0), subfacetName, 252.02909261530095); // electronics
+    assertHasStatFacetWithValue(topCatsResultBuckets.get(1), subfacetName, 0.0); // currency
+    assertHasStatFacetWithValue(topCatsResultBuckets.get(2), subfacetName, 129.99499893188477); // memory
   }
 
   @Test
@@ -323,13 +367,12 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
 
     QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
 
-    assertEquals(0, response.getStatus());
-    final SolrDocumentList returnedDocs = response.getResults();
-    assertEquals(NUM_TECHPRODUCTS_DOCS, returnedDocs.getNumFound());
-    assertEquals(10, returnedDocs.size());
-    final NamedList<Object> rawResponse = response.getResponse();
-    assertHasFacetWithBucketValues(rawResponse,"top_popular_cats", new FacetBucket("electronics",9),
-        new FacetBucket("graphics card", 2), new FacetBucket("hard drive", 2));
+    assertExpectedDocumentsFoundAndReturned(response, NUM_TECHPRODUCTS_DOCS, 10);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
+    assertHasFacetWithBucketValues(topLevelFacetData,"top_popular_cats",
+        new FacetBucket("electronics",9),
+        new FacetBucket("graphics card", 2),
+        new FacetBucket("hard drive", 2));
   }
 
   @Test
@@ -345,13 +388,12 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
 
     QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
 
-    assertEquals(0, response.getStatus());
-    final SolrDocumentList returnedDocs = response.getResults();
-    assertEquals(NUM_TECHPRODUCTS_DOCS, returnedDocs.getNumFound());
-    assertEquals(10, returnedDocs.size());
-    final NamedList<Object> rawResponse = response.getResponse();
-    assertHasFacetWithBucketValues(rawResponse,"top_popular_cats", new FacetBucket("electronics",9),
-        new FacetBucket("graphics card", 2), new FacetBucket("hard drive", 2));
+    assertExpectedDocumentsFoundAndReturned(response, NUM_TECHPRODUCTS_DOCS, 10);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
+    assertHasFacetWithBucketValues(topLevelFacetData,"top_popular_cats",
+        new FacetBucket("electronics",9),
+        new FacetBucket("graphics card", 2),
+        new FacetBucket("hard drive", 2));
   }
 
   @Test
@@ -366,13 +408,12 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
 
     QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
 
-    assertEquals(0, response.getStatus());
-    final SolrDocumentList returnedDocs = response.getResults();
-    assertEquals(NUM_ELECTRONICS, returnedDocs.getNumFound());
-    assertEquals(10, returnedDocs.size());
-    final NamedList<Object> rawResponse = response.getResponse();
-    assertHasFacetWithBucketValues(rawResponse,"top_cats", new FacetBucket("electronics",NUM_ELECTRONICS),
-        new FacetBucket("currency", NUM_CURRENCY), new FacetBucket("memory", NUM_MEMORY));
+    assertExpectedDocumentsFoundAndReturned(response, NUM_ELECTRONICS, 10);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
+    assertHasFacetWithBucketValues(topLevelFacetData,"top_cats",
+        new FacetBucket("electronics",NUM_ELECTRONICS),
+        new FacetBucket("currency", NUM_CURRENCY),
+        new FacetBucket("memory", NUM_MEMORY));
   }
 
   @Test
@@ -386,16 +427,14 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
 
     QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
 
-    assertEquals(0, response.getStatus());
-    final SolrDocumentList returnedDocs = response.getResults();
-    assertEquals(NUM_ELECTRONICS, returnedDocs.getNumFound());
-    assertEquals(10, returnedDocs.size());
-    final NamedList<Object> rawResponse = response.getResponse();
-    assertHasFacetWithBucketValues(rawResponse,"largest_search_cats",
+    assertExpectedDocumentsFoundAndReturned(response, NUM_ELECTRONICS, 10);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
+    assertHasFacetWithBucketValues(topLevelFacetData,"largest_search_cats",
         new FacetBucket("search",2),
         new FacetBucket("software", 2));
   }
 
+  @Test
   public void testFacetWithMultipleSimpleQueryClausesInArbitraryDomain() throws Exception {
     final TermsFacetMap solrCategoriesFacet = new TermsFacetMap("cat")
         .withDomain(new DomainMap()
@@ -407,16 +446,14 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
 
     QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
 
-    assertEquals(0, response.getStatus());
-    final SolrDocumentList returnedDocs = response.getResults();
-    assertEquals(NUM_ELECTRONICS, returnedDocs.getNumFound());
-    assertEquals(10, returnedDocs.size());
-    final NamedList<Object> rawResponse = response.getResponse();
-    assertHasFacetWithBucketValues(rawResponse,"cats_matching_solr",
+    assertExpectedDocumentsFoundAndReturned(response, NUM_ELECTRONICS, 10);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
+    assertHasFacetWithBucketValues(topLevelFacetData,"cats_matching_solr",
         new FacetBucket("search",1),
         new FacetBucket("software", 1));
   }
 
+  @Test
   public void testFacetWithMultipleLocalParamsQueryClausesInArbitraryDomain() throws Exception {
     final TermsFacetMap solrCategoriesFacet = new TermsFacetMap("cat")
         .withDomain(new DomainMap()
@@ -428,12 +465,9 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
 
     QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
 
-    assertEquals(0, response.getStatus());
-    final SolrDocumentList returnedDocs = response.getResults();
-    assertEquals(NUM_ELECTRONICS, returnedDocs.getNumFound());
-    assertEquals(10, returnedDocs.size());
-    final NamedList<Object> rawResponse = response.getResponse();
-    assertHasFacetWithBucketValues(rawResponse,"cats_matching_solr",
+    assertExpectedDocumentsFoundAndReturned(response, NUM_ELECTRONICS, 10);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
+    assertHasFacetWithBucketValues(topLevelFacetData,"cats_matching_solr",
         new FacetBucket("search",1),
         new FacetBucket("software", 1));
   }
@@ -454,19 +488,39 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
 
     QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
 
-    assertEquals(0, response.getStatus());
-    final SolrDocumentList returnedDocs = response.getResults();
-    assertEquals(NUM_IN_STOCK, returnedDocs.getNumFound());
-    assertEquals(10, returnedDocs.size());
-    final NamedList<Object> rawResponse = response.getResponse();
-    assertHasFacetWithBucketValues(rawResponse,"in_stock_only",
+    assertExpectedDocumentsFoundAndReturned(response, NUM_IN_STOCK, 10);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
+    assertHasFacetWithBucketValues(topLevelFacetData,"in_stock_only",
         new FacetBucket("electronics",8),
         new FacetBucket("currency", 4));
-    assertHasFacetWithBucketValues(rawResponse,"all",
+    assertHasFacetWithBucketValues(topLevelFacetData  ,"all",
         new FacetBucket("electronics",12),
         new FacetBucket("currency", 4));
   }
 
+  @Test
+  public void testRangeFacetWithOtherBucketsRequested() throws Exception {
+    final JsonQueryRequest request = new JsonQueryRequest()
+        .setQuery("*:*")
+        .withFacet("price_range",
+            new RangeFacetMap("price", 0, 100, 20)
+                .setOtherBuckets(RangeFacetMap.OtherBuckets.ALL)
+        );
+
+    QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
+    final NestableJsonFacet topLevelFacetData = response.getJsonFacetingResponse();
+
+    assertHasFacetWithBucketValues(topLevelFacetData, "price_range",
+        new FacetBucket(0.0f, 5),
+        new FacetBucket(20.0f, 0),
+        new FacetBucket(40.0f, 0),
+        new FacetBucket(60.0f, 1),
+        new FacetBucket(80.0f, 1));
+    assertEquals(0, topLevelFacetData.getBucketBasedFacets("price_range").getBefore());
+    assertEquals(9, topLevelFacetData.getBucketBasedFacets("price_range").getAfter());
+    assertEquals(7, topLevelFacetData.getBucketBasedFacets("price_range").getBetween());
+  }
+
   private class FacetBucket {
     private final Object val;
     private final int count;
@@ -479,52 +533,29 @@ public class JsonQueryRequestFacetingIntegrationTest extends SolrCloudTestCase {
     public int getCount() { return count; }
   }
 
-  private void assertHasFacetWithBucketValues(NamedList<Object> rawResponse, String expectedFacetName, FacetBucket... expectedBuckets) {
-    final NamedList<Object> facetsTopLevel = assertHasFacetResponse(rawResponse);
-    assertFacetResponseHasFacetWithBuckets(facetsTopLevel, expectedFacetName, expectedBuckets);
-  }
-
-  private void assertHasStatFacetWithValue(NamedList<Object> rawResponse, String expectedFacetName, Double expectedStatValue) {
-    final NamedList<Object> facetsTopLevel = assertHasFacetResponse(rawResponse);
-    assertFacetResponseHasStatFacetWithValue(facetsTopLevel, expectedFacetName, expectedStatValue);
-  }
-
-  private NamedList<Object> assertHasFacetResponse(NamedList<Object> topLevelResponse) {
-    Object o = topLevelResponse.get("facets");
-    if (o == null) fail("Response has no top-level 'facets' property as expected");
-    if (!(o instanceof NamedList)) fail("Response has a top-level 'facets' property, but it is not a NamedList");
-
-    return (NamedList<Object>) o;
-  }
-
-  private void assertFacetResponseHasFacetWithBuckets(NamedList<Object> facetResponse, String expectedFacetName, FacetBucket... expectedBuckets) {
-    Object o = facetResponse.get(expectedFacetName);
-    if (o == null) fail("Response has no top-level facet named '" + expectedFacetName + "'");
-    if (!(o instanceof NamedList)) fail("Response has a property for the expected facet '" + expectedFacetName + "' property, but it is not a NamedList");
-
-    final NamedList<Object> expectedFacetTopLevel = (NamedList<Object>) o;
-    o = expectedFacetTopLevel.get("buckets");
-    if (o == null) fail("Response has no 'buckets' property under 'facets'");
-    if (!(o instanceof List)) fail("Response has no 'buckets' property containing actual facet information.");
-
-    final List<NamedList> bucketList = (List<NamedList>) o;
-    assertEquals("Expected " + expectedBuckets.length + " buckets, but found " + bucketList.size(),
-        expectedBuckets.length, bucketList.size());
+  private void assertHasFacetWithBucketValues(NestableJsonFacet response, String expectedFacetName, FacetBucket... expectedBuckets) {
+    assertTrue("Expected response to have facet with name " + expectedFacetName,
+        response.getBucketBasedFacets(expectedFacetName) != null);
+    final List<BucketJsonFacet> buckets = response.getBucketBasedFacets(expectedFacetName).getBuckets();
+    assertEquals(expectedBuckets.length, buckets.size());
     for (int i = 0; i < expectedBuckets.length; i++) {
       final FacetBucket expectedBucket = expectedBuckets[i];
-      final NamedList<Object> actualBucket = bucketList.get(i);
-      assertEquals(expectedBucket.getVal(), actualBucket.get("val"));
-      assertEquals(expectedBucket.getCount(), actualBucket.get("count"));
+      final BucketJsonFacet actualBucket = buckets.get(i);
+      assertEquals(expectedBucket.getVal(), actualBucket.getVal());
+      assertEquals(expectedBucket.getCount(), actualBucket.getCount());
     }
   }
 
-  private void assertFacetResponseHasStatFacetWithValue(NamedList<Object> facetResponse, String expectedFacetName, Double expectedStatValue) {
-    Object o = facetResponse.get(expectedFacetName);
-    if (o == null) fail("Response has no top-level facet named '" + expectedFacetName + "'");
-    if (!(o instanceof Number)) fail("Response has a property for the expected facet '" + expectedFacetName + "' property, but it is not a Number");
+  private void assertHasStatFacetWithValue(NestableJsonFacet response, String expectedFacetName, Double expectedStatValue) {
+    assertTrue("Expected response to have stat facet named '" + expectedFacetName + "'",
+        response.getStatFacetValue(expectedFacetName) != null);
+    assertEquals(expectedStatValue, response.getStatFacetValue(expectedFacetName));
+  }
 
-    final Number actualStatValueAsNumber = (Number) o;
-    final Double actualStatValueAsDouble = ((Number) o).doubleValue();
-    assertEquals(expectedStatValue, actualStatValueAsDouble, 0.5);
+  private void assertExpectedDocumentsFoundAndReturned(QueryResponse response, int expectedNumFound, int expectedReturned) {
+    assertEquals(0, response.getStatus());
+    final SolrDocumentList documents = response.getResults();
+    assertEquals(expectedNumFound, documents.getNumFound());
+    assertEquals(expectedReturned, documents.size());
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/d17c6d88/solr/solrj/src/test/org/apache/solr/client/solrj/request/json/JsonQueryRequestHeatmapFacetingTest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/request/json/JsonQueryRequestHeatmapFacetingTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/request/json/JsonQueryRequestHeatmapFacetingTest.java
new file mode 100644
index 0000000..1ccd581
--- /dev/null
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/request/json/JsonQueryRequestHeatmapFacetingTest.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.client.solrj.request.json;
+
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.solr.client.solrj.request.CollectionAdminRequest;
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.client.solrj.response.json.HeatmapJsonFacet;
+import org.apache.solr.client.solrj.response.json.NestableJsonFacet;
+import org.apache.solr.cloud.SolrCloudTestCase;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.util.ExternalPaths;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class JsonQueryRequestHeatmapFacetingTest extends SolrCloudTestCase {
+  private static final String COLLECTION_NAME = "spatialdata";
+  private static final String CONFIG_NAME = "spatialdata_config";
+  private static final String FIELD = "location_srpt";
+
+  @BeforeClass
+  public static void setupCluster() throws Exception {
+    configureCluster(1)
+        .addConfig(CONFIG_NAME, new File(ExternalPaths.SOURCE_HOME, "solrj/src/test-files/solrj/solr/configsets/spatial/conf").toPath())
+        .configure();
+
+    final List<String> solrUrls = new ArrayList<>();
+    solrUrls.add(cluster.getJettySolrRunner(0).getBaseUrl().toString());
+
+    CollectionAdminRequest.createCollection(COLLECTION_NAME, CONFIG_NAME, 1, 1).process(cluster.getSolrClient());
+
+    indexSpatialData();
+  }
+
+  private static void indexSpatialData() throws Exception {
+    final SolrInputDocument doc1 = new SolrInputDocument("id", "0", FIELD, "ENVELOPE(100, 120, 80, 40)");
+    final SolrInputDocument doc2 = new SolrInputDocument("id", "1", FIELD, "ENVELOPE(-120, -110, 80, 20)");
+    final SolrInputDocument doc3 = new SolrInputDocument("id", "3", FIELD, "POINT(70 60)");
+    final SolrInputDocument doc4 = new SolrInputDocument("id", "4", FIELD, "POINT(91 89)");
+    final List<SolrInputDocument> docs = new ArrayList<>();
+    docs.add(doc1);
+    docs.add(doc2);
+    docs.add(doc3);
+    docs.add(doc4);
+
+    cluster.getSolrClient().add(COLLECTION_NAME, docs);
+    cluster.getSolrClient().commit(COLLECTION_NAME);
+  }
+
+
+
+  @Test
+  public void testHeatmapFacet() throws Exception {
+    final List<List<Integer>> expectedHeatmapGrid = Arrays.asList(
+        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
+    );
+    final JsonQueryRequest request = new JsonQueryRequest()
+        .setQuery("*:*")
+        .setLimit(0)
+        .withFacet("heatmapFacet", new HeatmapFacetMap(FIELD)
+            .setHeatmapFormat(HeatmapFacetMap.HeatmapFormat.INTS2D)
+            .setRegionQuery("[\"50 20\" TO \"180 90\"]")
+            .setGridLevel(4)
+        );
+
+    QueryResponse response = request.process(cluster.getSolrClient(), COLLECTION_NAME);
+    final NestableJsonFacet topLevelFacet = response.getJsonFacetingResponse();
+    final HeatmapJsonFacet heatmap = topLevelFacet.getHeatmapFacetByName("heatmapFacet");
+    final List<List<Integer>> actualHeatmapGrid = heatmap.getCountGrid();
+    assertEquals(expectedHeatmapGrid, actualHeatmapGrid);
+  }
+}