You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mi...@apache.org on 2014/01/20 19:56:26 UTC

svn commit: r1559805 - in /lucene/dev/branches/lucene5376/lucene: demo/src/java/org/apache/lucene/demo/facet/ facet/src/java/org/apache/lucene/facet/range/ server/src/java/org/apache/lucene/server/ server/src/java/org/apache/lucene/server/handlers/ ser...

Author: mikemccand
Date: Mon Jan 20 18:56:25 2014
New Revision: 1559805

URL: http://svn.apache.org/r1559805
Log:
LUCENE-5376: show how to do distance drill down with lucene server; clean up some tests

Added:
    lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestSimpleSpatial.java   (with props)
Modified:
    lucene/dev/branches/lucene5376/lucene/demo/src/java/org/apache/lucene/demo/facet/DistanceFacetsExample.java
    lucene/dev/branches/lucene5376/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRangeFacetCounts.java
    lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/handlers/RegisterFieldHandler.java
    lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/handlers/SearchHandler.java
    lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/package.html
    lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/ServerBaseTestCase.java
    lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestFacets.java
    lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestSnapshots.java

Modified: lucene/dev/branches/lucene5376/lucene/demo/src/java/org/apache/lucene/demo/facet/DistanceFacetsExample.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5376/lucene/demo/src/java/org/apache/lucene/demo/facet/DistanceFacetsExample.java?rev=1559805&r1=1559804&r2=1559805&view=diff
==============================================================================
--- lucene/dev/branches/lucene5376/lucene/demo/src/java/org/apache/lucene/demo/facet/DistanceFacetsExample.java (original)
+++ lucene/dev/branches/lucene5376/lucene/demo/src/java/org/apache/lucene/demo/facet/DistanceFacetsExample.java Mon Jan 20 18:56:25 2014
@@ -108,7 +108,6 @@ public class DistanceFacetsExample imple
   /** User runs a query and counts facets. */
   public FacetResult search() throws IOException {
 
-
     FacetsCollector fc = new FacetsCollector();
 
     searcher.search(new MatchAllDocsQuery(), fc);

Modified: lucene/dev/branches/lucene5376/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRangeFacetCounts.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5376/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRangeFacetCounts.java?rev=1559805&r1=1559804&r2=1559805&view=diff
==============================================================================
--- lucene/dev/branches/lucene5376/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRangeFacetCounts.java (original)
+++ lucene/dev/branches/lucene5376/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRangeFacetCounts.java Mon Jan 20 18:56:25 2014
@@ -71,7 +71,6 @@ public class DoubleRangeFacetCounts exte
     LongRange[] longRanges = new LongRange[ranges.length];
     for(int i=0;i<ranges.length;i++) {
       DoubleRange range = ranges[i];
-      System.out.println("range " + i + ": " + range);
       longRanges[i] =  new LongRange(range.label,
                                      NumericUtils.doubleToSortableLong(range.minIncl), true,
                                      NumericUtils.doubleToSortableLong(range.maxIncl), true);

Modified: lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/handlers/RegisterFieldHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/handlers/RegisterFieldHandler.java?rev=1559805&r1=1559804&r2=1559805&view=diff
==============================================================================
--- lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/handlers/RegisterFieldHandler.java (original)
+++ lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/handlers/RegisterFieldHandler.java Mon Jan 20 18:56:25 2014
@@ -420,6 +420,7 @@ public class RegisterFieldHandler extend
 
     FieldType ft = new FieldType();
 
+    // nocommit why do we have storeDocValues?  it's too low level?
     boolean dv = f.getBoolean("storeDocValues");
     boolean sorted = f.getBoolean("sort");
     boolean grouped = f.getBoolean("group");

Modified: lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/handlers/SearchHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/handlers/SearchHandler.java?rev=1559805&r1=1559804&r2=1559805&view=diff
==============================================================================
--- lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/handlers/SearchHandler.java (original)
+++ lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/handlers/SearchHandler.java Mon Jan 20 18:56:25 2014
@@ -1636,7 +1636,8 @@ public class SearchHandler extends Handl
 
   static void fillFacetResults(Request r, SearcherAndTaxonomy s, FacetsCollector drillDowns,
                                FacetsCollector[] drillSideways, String[] drillSidewaysDims,
-                               IndexState state, JSONArray facetResults) throws IOException {
+                               IndexState state, JSONArray facetResults,
+                               Map<String,FieldDef> dynamicFields) throws IOException {
 
     Map<String,FacetsCollector> dsDimMap = new HashMap<String,FacetsCollector>();
     if (drillSidewaysDims != null) {
@@ -1655,13 +1656,18 @@ public class SearchHandler extends Handl
 
     for(Object o2 : r.getList("facets")) {
       Request r2 = (Request) o2;
-
-      FieldDef fd = state.getField(r2, "dim");
+      String fieldName = r2.getString("dim");
+      FieldDef fd = dynamicFields.get(fieldName);
+      if (fd == null) {
+        r2.fail("dim", "field \"" + fieldName + "\" was not registered and was not specified as a dynamicField");
+        // Dead code but compiler disagrees:
+        fd = null;
+      }
 
       FacetResult facetResult;
 
       if (r2.hasParam("numericRanges")) {
-        if (!fd.faceted.equals("numericRange")) {
+        if (fd.faceted != null && !fd.faceted.equals("numericRange")) {
           r2.fail("numericRanges", "field \"" + fd.name + "\" was not registered with facet=numericRange");
         }
         if (fd.valueType.equals("int") || fd.valueType.equals("long")) {
@@ -1685,7 +1691,7 @@ public class SearchHandler extends Handl
                                                    c,
                                                    ranges);
           facetResult = facets.getTopChildren(0, fd.name);
-        } else if (fd.valueType.equals("float") || fd.valueType.equals("double")) {
+        } else if (fd.valueType.equals("float") || fd.valueType.equals("double") || fd.valueType.equals("virtual")) {
           List<Object> rangeList = r2.getList("numericRanges");
           DoubleRange[] ranges = new DoubleRange[rangeList.size()];
           for(int i=0;i<ranges.length;i++) {
@@ -1702,9 +1708,17 @@ public class SearchHandler extends Handl
             c = drillDowns;
           }
 
-          Facets facets = new DoubleRangeFacetCounts(fd.name,
-                                                     c,
-                                                     ranges);
+          Facets facets;
+          if (fd.valueType.equals("virtual")) {
+            facets = new DoubleRangeFacetCounts(fd.name,
+                                                fd.valueSource,
+                                                c,
+                                                ranges);
+          } else {
+            facets = new DoubleRangeFacetCounts(fd.name,
+                                                c,
+                                                ranges);
+          }
           facetResult = facets.getTopChildren(0, fd.name);
         } else {
           // nocommit float/double too
@@ -1902,7 +1916,7 @@ public class SearchHandler extends Handl
 
     JSONObject diagnostics = new JSONObject();
 
-    Map<String,FieldDef> dynamicFields = getDynamicFields(state, r);
+    final Map<String,FieldDef> dynamicFields = getDynamicFields(state, r);
 
     Query q = extractQuery(state, r, timeStamp, useBlockJoinCollector, dynamicFields);
 
@@ -2164,7 +2178,7 @@ public class SearchHandler extends Handl
 
             @Override
             protected Facets buildFacetsResult(FacetsCollector drillDowns, FacetsCollector[] drillSideways, String[] drillSidewaysDims) throws IOException {
-              fillFacetResults(r, s, drillDowns, drillSideways, drillSidewaysDims, indexState, facetResults);
+              fillFacetResults(r, s, drillDowns, drillSideways, drillSidewaysDims, indexState, facetResults, dynamicFields);
               return null;
             }
 

Modified: lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/package.html
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/package.html?rev=1559805&r1=1559804&r2=1559805&view=diff
==============================================================================
--- lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/package.html (original)
+++ lucene/dev/branches/lucene5376/lucene/server/src/java/org/apache/lucene/server/package.html Mon Jan 20 18:56:25 2014
@@ -29,6 +29,10 @@
 	  joins, grouping, highlighting, suggest, live-values,
 	  snapshots, etc.
 
+	<li> Lucene's legacy FieldCache is never used; only the
+	  faster, more RAM efficient doc values are used when you
+	  sort, group, facet on a field.
+
 	<li> All searching is based on near-real-time IndexReader; you
 	  configure the minimum and maximum refresh times.
 
@@ -60,8 +64,8 @@
 	  searching.
 
 	<li> A server thread pool handles all concurrency during
-	  indexing, so you a single client thread can use the bulk
-	  indexing API and take advantage of the server computer's
+	  indexing, so a single client thread using the bulk
+	  indexing API will take advantage of the server computer's
 	  concurrent hardware.
 
 	<li> Settings are divided into <em>live</em> settings, which

Modified: lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/ServerBaseTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/ServerBaseTestCase.java?rev=1559805&r1=1559804&r2=1559805&view=diff
==============================================================================
--- lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/ServerBaseTestCase.java (original)
+++ lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/ServerBaseTestCase.java Mon Jan 20 18:56:25 2014
@@ -54,13 +54,25 @@ public abstract class ServerBaseTestCase
   private static Thread serverThread;
   static int port;
 
+  /** Current index name; we auto-insert this to outgoing
+   *  commands that need it. */
+
   protected static String curIndexName = "index";
   protected static boolean useDefaultIndex = true;
   
   protected static File STATE_DIR;
 
+  /** Last result from the server; tests can access this to
+   *  check results. */
   protected static JSONObject lastResult;
   
+  /** We record the last indexGen we saw return from the
+   *  server, and then insert that for search command if no
+   *  searcher is already specified.  This avoids a common
+   *  test bug of forgetting to specify which indexGen to
+   *  search. */
+  private static long lastIndexGen = -1;
+
   @BeforeClass
   public static void beforeClassServerBase() throws Exception {
     File dir = _TestUtil.getTempDir("ServerBase");
@@ -78,6 +90,7 @@ public abstract class ServerBaseTestCase
   @Override
   public void setUp() throws Exception {
     super.setUp();
+    lastIndexGen = -1;
     if (useDefaultIndex) {
       curIndexName = "index";
 
@@ -178,6 +191,7 @@ public abstract class ServerBaseTestCase
       serverThread.join();
       serverThread = null;
     }
+    lastIndexGen = -1;
   }
 
   protected static void deleteAllDocs() throws Exception {
@@ -249,6 +263,15 @@ public abstract class ServerBaseTestCase
       args.put("indexName", curIndexName);
     }
 
+    if (command.equals("search") && args.containsKey("searcher") == false && lastIndexGen != -1) {
+      if (VERBOSE) {
+        System.out.println("\nNOTE: ServerBaseTestCase: inserting 'searcher: {indexGen: " + lastIndexGen + "}' into search request");
+      }
+      JSONObject o = new JSONObject();
+      o.put("indexGen", lastIndexGen);
+      args.put("searcher", o);
+    }
+
     if (VERBOSE) {
       System.out.println("\nNOTE: ServerBaseTestCase: sendRaw command=" + command + " args:\n" + args.toJSONString(new JSONStyleIdent()));
     }
@@ -259,6 +282,13 @@ public abstract class ServerBaseTestCase
       System.out.println("NOTE: ServerBaseTestCase: server response:\n" + lastResult.toJSONString(new JSONStyleIdent()));
     }
 
+    if (lastResult.containsKey("indexGen")) {
+      lastIndexGen = getLong(lastResult, "indexGen");
+      if (VERBOSE) {
+        System.out.println("NOTE: ServerBaseTestCase: record lastIndexGen=" + lastIndexGen);
+      }
+    }
+
     return lastResult;
   }
 
@@ -370,7 +400,7 @@ public abstract class ServerBaseTestCase
 
   /** Simple xpath-like utility method to jump down and grab
    *  something out of the JSON response. */
-  protected Object get(Object o, String path) {
+  protected static Object get(Object o, String path) {
     int upto = 0;
     int tokStart = 0;
     boolean inArrayIndex = false;
@@ -414,63 +444,63 @@ public abstract class ServerBaseTestCase
     return o;
   }
 
-  protected String getString(Object o, String path) {
+  protected static String getString(Object o, String path) {
     return (String) get(o, path);
   }
 
-  protected String getString(String path) {
+  protected static String getString(String path) {
     return getString(lastResult, path);
   }
 
-  protected int getInt(Object o, String path) {
+  protected static int getInt(Object o, String path) {
     return ((Number) get(o, path)).intValue();
   }
 
-  protected int getInt(String path) {
+  protected static int getInt(String path) {
     return getInt(lastResult, path);
   }
 
-  protected boolean getBoolean(Object o, String path) {
+  protected static boolean getBoolean(Object o, String path) {
     return ((Boolean) get(o, path)).booleanValue();
   }
 
-  protected boolean getBoolean(String path) {
+  protected static boolean getBoolean(String path) {
     return getBoolean(lastResult, path);
   }
 
-  protected long getLong(Object o, String path) {
+  protected static long getLong(Object o, String path) {
     return ((Number) get(o, path)).longValue();
   }
 
-  protected long getLong(String path) {
+  protected static long getLong(String path) {
     return getLong(lastResult, path);
   }
 
-  protected float getFloat(Object o, String path) {
+  protected static float getFloat(Object o, String path) {
     return ((Number) get(o, path)).floatValue();
   }
 
-  protected float getFloat(String path) {
+  protected static float getFloat(String path) {
     return getFloat(lastResult, path);
   }
 
-  protected JSONObject getObject(Object o, String path) {
+  protected static JSONObject getObject(Object o, String path) {
     return (JSONObject) get(o, path);
   }
 
-  protected JSONObject getObject(String path) {
+  protected static JSONObject getObject(String path) {
     return getObject(lastResult, path);
   }
 
-  protected JSONArray getArray(Object o, String path) {
+  protected static JSONArray getArray(Object o, String path) {
     return (JSONArray) get(o, path);
   }
 
-  protected JSONArray getArray(String path) {
+  protected static JSONArray getArray(String path) {
     return getArray(lastResult, path);
   }
 
-  protected JSONArray getArray(JSONArray o, int index) {
+  protected static JSONArray getArray(JSONArray o, int index) {
     return (JSONArray) o.get(index);
   }
 

Modified: lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestFacets.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestFacets.java?rev=1559805&r1=1559804&r2=1559805&view=diff
==============================================================================
--- lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestFacets.java (original)
+++ lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestFacets.java Mon Jan 20 18:56:25 2014
@@ -156,29 +156,21 @@ public class TestFacets extends ServerBa
     deleteAllDocs();
     addDocument(0, "Bob", "this is a test", 10.99f, "2012/10/17");
     addDocument(1, "Lisa", "this is a another test", 11.99f, "2012/10/1");
-    long gen = addDocument(2, "Frank", "this is a third test", 12.99f, "2010/10/1");
-    JSONObject o = search("test", gen, "price", false, true, null, null);
-    assertEquals(3, ((Number) o.get("totalHits")).intValue());
-
-    JSONArray hits = (JSONArray) o.get("hits");
-    assertEquals(3, hits.size());
-
-    JSONObject hit = (JSONObject) hits.get(0);
-    assertEquals(0, ((JSONObject) hit.get("fields")).get("id"));
-    assertEquals("2012/10/17", ((JSONObject) hit.get("fields")).get("date"));
-
-    hit = (JSONObject) hits.get(1);
-    assertEquals(1, ((JSONObject) hit.get("fields")).get("id"));
-    assertEquals("2012/10/1", ((JSONObject) hit.get("fields")).get("date"));
-
-    hit = (JSONObject) hits.get(2);
-    assertEquals(2, ((JSONObject) hit.get("fields")).get("id"));
-    assertEquals("2010/10/1", ((JSONObject) hit.get("fields")).get("date"));
-    JSONArray facets = getArray(o, "facets[0].counts");
-    assertEquals(3, facets.size());
-    assertEquals("[\"top\",3]", facets.get(0).toString());
-    assertEquals("[\"2012\",2]", facets.get(1).toString());
-    assertEquals("[\"2010\",1]", facets.get(2).toString());
+    addDocument(2, "Frank", "this is a third test", 12.99f, "2010/10/1");
+    search("test", -1, "price", false, true, null, null);
+    assertEquals(3, getInt("totalHits"));
+    assertEquals(3, getInt("hits.length"));
+
+    assertEquals(0, getInt("hits[0].fields.id"));
+    assertEquals("2012/10/17", getString("hits[0].fields.date"));
+
+    assertEquals(1, getInt("hits[1].fields.id"));
+    assertEquals("2012/10/1", getString("hits[1].fields.date"));
+
+    assertEquals(2, getInt("hits[2].fields.id"));
+    assertEquals("2010/10/1", getString("hits[2].fields.date"));
+
+    assertEquals("top: 3, 2012: 2, 2010: 1", formatFacetCounts(getObject("facets[0]")));
   }    
 
   public void testFacetsReopen() throws Exception {
@@ -187,30 +179,21 @@ public class TestFacets extends ServerBa
     addDocument(1, "Lisa", "this is a another test", 11.99f, "2012/10/1");
     commit();
 
-    long gen = addDocument(2, "Frank", "this is a third test", 12.99f, "2010/10/1");
-    JSONObject o = search("test", gen, "price", false, true, null, null);
-    assertEquals(3, ((Number) o.get("totalHits")).intValue());
-
-    JSONArray hits = (JSONArray) o.get("hits");
-    assertEquals(3, hits.size());
-
-    JSONObject hit = (JSONObject) hits.get(0);
-    assertEquals(0, ((JSONObject) hit.get("fields")).get("id"));
-    assertEquals("2012/10/17", ((JSONObject) hit.get("fields")).get("date"));
-
-    hit = (JSONObject) hits.get(1);
-    assertEquals(1, ((JSONObject) hit.get("fields")).get("id"));
-    assertEquals("2012/10/1", ((JSONObject) hit.get("fields")).get("date"));
-
-    hit = (JSONObject) hits.get(2);
-    assertEquals(2, ((JSONObject) hit.get("fields")).get("id"));
-    assertEquals("2010/10/1", ((JSONObject) hit.get("fields")).get("date"));
-
-    JSONArray facets = getArray(o, "facets[0].counts");
-    assertEquals(3, facets.size());
-    assertEquals("[\"top\",3]", facets.get(0).toString());
-    assertEquals("[\"2012\",2]", facets.get(1).toString());
-    assertEquals("[\"2010\",1]", facets.get(2).toString());
+    addDocument(2, "Frank", "this is a third test", 12.99f, "2010/10/1");
+    search("test", -1, "price", false, true, null, null);
+    assertEquals(3, getInt("totalHits"));
+    assertEquals(3, getInt("hits.length"));
+
+    assertEquals(0, getInt("hits[0].fields.id"));
+    assertEquals("2012/10/17", getString("hits[0].fields.date"));
+
+    assertEquals(1, getInt("hits[1].fields.id"));
+    assertEquals("2012/10/1", getString("hits[1].fields.date"));
+
+    assertEquals(2, getInt("hits[2].fields.id"));
+    assertEquals("2010/10/1", getString("hits[2].fields.date"));
+
+    assertEquals("top: 3, 2012: 2, 2010: 1", formatFacetCounts(getObject("facets[0]")));
   }    
 
   public void testDrillSideways() throws Exception {
@@ -220,48 +203,40 @@ public class TestFacets extends ServerBa
     send("addDocument", "{fields: {author: Lisa}}");
     send("addDocument", "{fields: {author: Tom}}");
     send("addDocument", "{fields: {author: Tom}}");
-    long indexGen = getLong(send("addDocument", "{fields: {author: Tom}}"), "indexGen");
+    send("addDocument", "{fields: {author: Tom}}");
 
     // Initial query:
-    JSONObject o = send("search", String.format(Locale.ROOT, "{query: MatchAllDocsQuery, facets: [{dim: author, topN: 10}], searcher: {indexGen: %d}}", indexGen));
-    assertEquals(6, o.get("totalHits"));
-    assertEquals("[[\"top\",6],[\"Tom\",3],[\"Lisa\",2],[\"Bob\",1]]", getArray(o, "facets[0].counts").toString());
+    send("search", "{query: MatchAllDocsQuery, facets: [{dim: author, topN: 10}]}");
+    assertEquals(6, getInt("totalHits"));
+    assertEquals("top: 6, Tom: 3, Lisa: 2, Bob: 1", formatFacetCounts(getObject("facets[0]")));
 
     // Now, single drill down:
-    o = send("search", String.format(Locale.ROOT, "{drillDowns: [{field: author, value: Bob}], query: MatchAllDocsQuery, facets: [{dim: author, topN: 10}], searcher: {indexGen: %d}}", indexGen));
-    assertEquals(1, o.get("totalHits"));
-    assertEquals("[[\"top\",6],[\"Tom\",3],[\"Lisa\",2],[\"Bob\",1]]", getArray(o, "facets[0].counts").toString());
+    send("search", "{drillDowns: [{field: author, value: Bob}], query: MatchAllDocsQuery, facets: [{dim: author, topN: 10}]}");
+    assertEquals(1, getInt("totalHits"));
+    assertEquals("top: 6, Tom: 3, Lisa: 2, Bob: 1", formatFacetCounts(getObject("facets[0]")));
 
     // Multi (OR'd) drill down:
-    o = send("search", String.format(Locale.ROOT, "{drillDowns: [{field: author, value: Bob}, {field: author, value: Lisa}], query: MatchAllDocsQuery, facets: [{dim: author, topN: 10}], searcher: {indexGen: %d}}", indexGen));
-    assertEquals(3, o.get("totalHits"));
-    assertEquals("[[\"top\",6],[\"Tom\",3],[\"Lisa\",2],[\"Bob\",1]]", getArray(o, "facets[0].counts").toString());
+    send("search", "{drillDowns: [{field: author, value: Bob}, {field: author, value: Lisa}], query: MatchAllDocsQuery, facets: [{dim: author, topN: 10}]}");
+    assertEquals(3, getInt("totalHits"));
+    assertEquals("top: 6, Tom: 3, Lisa: 2, Bob: 1", formatFacetCounts(getObject("facets[0]")));
   }
 
   public void testLongRangeFacets() throws Exception {
     deleteAllDocs();    
-    long gen = -1;
     for(int i=0;i<100;i++) {
-      gen = getLong(send("addDocument", "{fields: {longField: " + i + "}}"), "indexGen");
+      send("addDocument", "{fields: {longField: " + i + "}}");
     }
-    JSONObject o = send("search", "{facets: [{dim: longField, numericRanges: [{label: All, min: 0, max: 99, minInclusive: true, maxInclusive: true}, {label: Half, min: 0, max: 49, minInclusive: true, maxInclusive: true}]}], searcher: {indexGen: " + gen + "}}");
-    assertEquals("All", getString(o, "facets[0].counts[1][0]"));
-    assertEquals(100, getInt(o, "facets[0].counts[1][1]"));
-    assertEquals("Half", getString(o, "facets[0].counts[2][0]"));
-    assertEquals(50, getInt(o, "facets[0].counts[2][1]"));
+    send("search", "{facets: [{dim: longField, numericRanges: [{label: All, min: 0, max: 99, minInclusive: true, maxInclusive: true}, {label: Half, min: 0, max: 49, minInclusive: true, maxInclusive: true}]}]}");
+    assertEquals("top: 100, All: 100, Half: 50", formatFacetCounts(getObject("facets[0]")));
   }
 
   public void testDoubleRangeFacets() throws Exception {
     deleteAllDocs();    
-    long gen = -1;
     for(int i=0;i<100;i++) {
-      gen = getLong(send("addDocument", "{fields: {doubleField: " + i + "}}"), "indexGen");
+      send("addDocument", "{fields: {doubleField: " + i + "}}");
     }
-    JSONObject o = send("search", "{facets: [{dim: doubleField, numericRanges: [{label: All, min: 0, max: 99, minInclusive: true, maxInclusive: true}, {label: Half, min: 0, max: 49, minInclusive: true, maxInclusive: true}]}], searcher: {indexGen: " + gen + "}}");
-    assertEquals("All", getString(o, "facets[0].counts[1][0]"));
-    assertEquals(100, getInt(o, "facets[0].counts[1][1]"));
-    assertEquals("Half", getString(o, "facets[0].counts[2][0]"));
-    assertEquals(50, getInt(o, "facets[0].counts[2][1]"));
+    send("search", "{facets: [{dim: doubleField, numericRanges: [{label: All, min: 0, max: 99, minInclusive: true, maxInclusive: true}, {label: Half, min: 0, max: 49, minInclusive: true, maxInclusive: true}]}]}");
+    assertEquals("top: 100, All: 100, Half: 50", formatFacetCounts(getObject("facets[0]")));
   }
 
   // nocommit fails ... we need to add FloatRangeFacetCounts
@@ -319,15 +294,15 @@ public class TestFacets extends ServerBa
     send("addDocument", "{fields: {ssdv: three}}");
     send("commit");
     send("addDocument", "{fields: {ssdv: one}}");
-    long indexGen = getLong(send("addDocument", "{fields: {ssdv: one}}"), "indexGen");
+    send("addDocument", "{fields: {ssdv: one}}");
 
     for(int i=0;i<2;i++) {
       // nocommit if i remove indexGen from here, the error
       // message is bad: it says "each element in the array
       // my have these params:..." when it shouldn't
-      JSONObject result = send("search", "{query: MatchAllDocsQuery, facets: [{dim: ssdv}], searcher: {indexGen: " + indexGen + "}}");
-      assertEquals(6, getInt(result, "totalHits"));
-      assertEquals("[[\"top\",6],[\"one\",3],[\"two\",2],[\"three\",1]]", getArray(result, "facets[0].counts").toString());
+      send("search", "{query: MatchAllDocsQuery, facets: [{dim: ssdv}]}");
+      assertEquals(6, getInt("totalHits"));
+      assertEquals("top: 6, one: 3, two: 2, three: 1", formatFacetCounts(getObject("facets[0]")));
 
       // Make sure suggest survives server restart:    
       shutdownServer();
@@ -335,5 +310,20 @@ public class TestFacets extends ServerBa
       send("startIndex");
     }
   }
+
+  public static String formatFacetCounts(JSONObject facets) {
+    StringBuilder sb = new StringBuilder();
+    JSONArray arr = getArray(facets, "counts");
+    for(Object o : arr) {
+      JSONArray facet = (JSONArray) o;
+      sb.append(facet.get(0));
+      sb.append(": ");
+      sb.append(facet.get(1));
+      sb.append(", ");
+    }
+    String s = sb.toString();
+    // remove last ', ':
+    return s.substring(0, s.length()-2);
+  }
 }
 

Added: lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestSimpleSpatial.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestSimpleSpatial.java?rev=1559805&view=auto
==============================================================================
--- lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestSimpleSpatial.java (added)
+++ lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestSimpleSpatial.java Mon Jan 20 18:56:25 2014
@@ -0,0 +1,79 @@
+package org.apache.lucene.server;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.util.Locale;
+
+import org.apache.lucene.util._TestUtil;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import net.minidev.json.JSONArray;
+import net.minidev.json.JSONObject;
+
+/** Simple example of how to do distance drill-downs. */
+public class TestSimpleSpatial extends ServerBaseTestCase {
+
+  @BeforeClass
+  public static void init() throws Exception {
+    useDefaultIndex = false;
+    curIndexName = "spatial";
+    startServer();
+    createAndStartIndex();
+  }
+
+  @AfterClass
+  public static void fini() throws Exception {
+    shutdownServer();
+  }
+
+  public void test() throws Exception {
+
+    // Record latitude and longitude as double fields:
+    send("registerFields",
+         "{fields: {latitude: {type: double, storeDocValues: true}, longitude: {type: double, storeDocValues: true}}}");
+
+    // Index 3 documents each with its own location:
+    send("addDocument", "{fields: {latitude: 40.759011, longitude: -73.9844722}}");
+    send("addDocument", "{fields: {latitude: 40.718266, longitude: -74.007819}}");
+    send("addDocument", "{fields: {latitude: 40.7051157, longitude: -74.0088305}}");
+
+    // Search, matching all documents and counting distance
+    // facets from the home origin:
+    double homeLatitude = 40.7143528;
+    double homeLongitude = -74.0059731;
+    send("search",
+         "{query: MatchAllDocsQuery, " +
+         "virtualFields: [{name: distance, expression: 'haversin(" + homeLatitude + "," + homeLongitude + ",latitude,longitude)'}], " +
+         "facets: [{dim: distance, numericRanges: [" + 
+         "{label: '< 1 km', min: 0.0, minInclusive: true, max: 1.0, maxInclusive: false}," +
+         "{label: '< 2 km', min: 0.0, minInclusive: true, max: 2.0, maxInclusive: false}," +
+         "{label: '< 5 km', min: 0.0, minInclusive: true, max: 5.0, maxInclusive: false}," +
+         "{label: '< 10 km', min: 0.0, minInclusive: true, max: 10.0, maxInclusive: false}," +
+         "]}]}");
+
+    // Search, matching all documents and counting distance
+    // facets from the home origin:
+    assertEquals(3, getInt("totalHits"));
+    assertEquals("top: 3, < 1 km: 1, < 2 km: 2, < 5 km: 2, < 10 km: 3",
+                 TestFacets.formatFacetCounts(getObject("facets[0]")));
+
+    // nocommit show drill down too
+  }
+}
+

Modified: lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestSnapshots.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestSnapshots.java?rev=1559805&r1=1559804&r2=1559805&view=diff
==============================================================================
--- lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestSnapshots.java (original)
+++ lucene/dev/branches/lucene5376/lucene/server/src/test/org/apache/lucene/server/TestSnapshots.java Mon Jan 20 18:56:25 2014
@@ -66,7 +66,8 @@ public class TestSnapshots extends Serve
     send("deleteDocuments", "{field: id, values: ['0']}");
     send("registerFields", "{fields: {field: {type: 'atom'}}}");
     send("addDocument", "{fields: {body: 'here is the body', id: '1', facet: 'facet2', field: 'abc'}}");
-    long indexGen2 = getLong(send("addDocument", "{fields: {body: 'here is the body', id: '2', facet: 'facet2', field: 'abc'}}"), "indexGen");
+    send("addDocument", "{fields: {body: 'here is the body', id: '2', facet: 'facet2', field: 'abc'}}");
+    long indexGen2 = getLong("indexGen");
     commit();
 
     File backupDir = _TestUtil.getTempDir("backup");
@@ -91,14 +92,14 @@ public class TestSnapshots extends Serve
       }
 
       // Make sure we can search the snapshot and only get 1 hit:
-      JSONObject searchResult = send("search", "{retrieveFields: [id], searcher: {snapshot: \"" + snapshotID + "\"}, query: MatchAllDocsQuery}");
-      assertEquals(1, getInt(searchResult, "totalHits"));
-      assertEquals("0", getString(searchResult, "hits[0].fields.id"));
+      send("search", "{retrieveFields: [id], searcher: {snapshot: \"" + snapshotID + "\"}, query: MatchAllDocsQuery}");
+      assertEquals(1, getInt("totalHits"));
+      assertEquals("0", getString("hits[0].fields.id"));
 
       // Make sure we can search the current searcher and we
       // get 2 hits:
-      searchResult = send("search", "{retrieveFields: [id], searcher: {indexGen: " + indexGen2 + "}, query: MatchAllDocsQuery}");
-      assertEquals(2, getInt(searchResult, "totalHits"));
+      send("search", "{retrieveFields: [id], searcher: {indexGen: " + indexGen2 + "}, query: MatchAllDocsQuery}");
+      assertEquals(2, getInt("totalHits"));
 
       // Bounce the server:
       shutdownServer();
@@ -106,14 +107,14 @@ public class TestSnapshots extends Serve
       send("startIndex");
 
       // Make sure we can search the snapshot and still only get 1 hit:
-      searchResult = send("search", "{retrieveFields: [id], searcher: {snapshot: \"" + snapshotID + "\"}, query: MatchAllDocsQuery}");
-      assertEquals(1, getInt(searchResult, "totalHits"));
-      assertEquals("0", getString(searchResult, "hits[0].fields.id"));
+      send("search", "{retrieveFields: [id], searcher: {snapshot: \"" + snapshotID + "\"}, query: MatchAllDocsQuery}");
+      assertEquals(1, getInt("totalHits"));
+      assertEquals("0", getString("hits[0].fields.id"));
 
       // Make sure we can search the current searcher and we
       // get 2 hits:
-      searchResult = send("search", "{retrieveFields: [id], query: MatchAllDocsQuery}");
-      assertEquals(2, getInt(searchResult, "totalHits"));
+      send("search", "{retrieveFields: [id], query: MatchAllDocsQuery}");
+      assertEquals(2, getInt("totalHits"));
 
       // Make sure files still exist (snapshot persisted):
       for(Map.Entry<String,Object> ent : result.entrySet()) {
@@ -129,9 +130,9 @@ public class TestSnapshots extends Serve
       }
 
       // Make sure we can still search the snapshot:
-      searchResult = send("search", "{retrieveFields: [id], searcher: {snapshot: \"" + snapshotID + "\"}, query: MatchAllDocsQuery}");
-      assertEquals(1, getInt(searchResult, "totalHits"));
-      assertEquals("0", getString(searchResult, "hits[0].fields.id"));
+      send("search", "{retrieveFields: [id], searcher: {snapshot: \"" + snapshotID + "\"}, query: MatchAllDocsQuery}");
+      assertEquals(1, getInt("totalHits"));
+      assertEquals("0", getString("hits[0].fields.id"));
 
       // Now, release the snapshot:
       send("releaseSnapshot", "{id: \"" + snapshotID + "\"}");