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 2013/12/03 00:44:14 UTC

svn commit: r1547241 [1/2] - in /lucene/dev/branches/lucene5339: ./ lucene/demo/src/java/org/apache/lucene/demo/facet/ lucene/demo/src/test/org/apache/lucene/demo/facet/ lucene/facet/src/java/org/apache/lucene/facet/ lucene/facet/src/java/org/apache/lu...

Author: mikemccand
Date: Mon Dec  2 23:44:13 2013
New Revision: 1547241

URL: http://svn.apache.org/r1547241
Log:
LUCENE-5339: nocommits, javadocs, tests, range drill downs

Modified:
    lucene/dev/branches/lucene5339/TODO
    lucene/dev/branches/lucene5339/lucene/demo/src/java/org/apache/lucene/demo/facet/DistanceFacetsExample.java
    lucene/dev/branches/lucene5339/lucene/demo/src/java/org/apache/lucene/demo/facet/RangeFacetsExample.java
    lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAssociationsFacetsExample.java
    lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestDistanceFacetsExample.java
    lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestExpressionAggregationFacetsExample.java
    lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestMultiCategoryListsFacetsExample.java
    lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestRangeFacetsExample.java
    lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleFacetsExample.java
    lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleSortedSetFacetsExample.java
    lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/DoubleRange.java
    lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/DoubleRangeFacetCounts.java
    lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/FacetResult.java
    lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/FloatTaxonomyFacets.java
    lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/IntTaxonomyFacets.java
    lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/LongRange.java
    lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/LongRangeFacetCounts.java
    lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/SortedSetDocValuesFacetCounts.java
    lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/TaxonomyFacets.java
    lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/FacetLabel.java
    lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyWriter.java
    lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/writercache/CompactLabelToOrdinal.java
    lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/writercache/NameHashIntCacheLRU.java
    lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/FacetTestCase.java
    lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java
    lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestMultipleIndexFields.java
    lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestRangeFacetCounts.java
    lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestSortedSetDocValuesFacets.java
    lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestTaxonomyFacetAssociations.java
    lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestTaxonomyFacetCounts.java
    lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestTaxonomyFacetSumValueSource.java
    lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestFacetLabel.java
    lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyCombined.java
    lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/directory/TestConcurrentFacetedIndexing.java
    lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/directory/TestDirectoryTaxonomyWriter.java
    lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/writercache/TestCompactLabelToOrdinal.java

Modified: lucene/dev/branches/lucene5339/TODO
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/TODO?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/TODO (original)
+++ lucene/dev/branches/lucene5339/TODO Mon Dec  2 23:44:13 2013
@@ -7,11 +7,9 @@ TODO
   - getSpecificValue for a dim isn't reliable
   - we could put more stuff into the "schema", e.g. this field is
     sorted-set-DV and that one is taxo?
-  - standardize on facet or facets (e.g. FacetIndexWriter)
-  - fewer args when constructing a range
   - how to do avg() agg?
-  - consistently name things "dimension"? calling these fields is CONFUSING
   - later
+    - fewer args when constructing a range
     - SSDVValueSourceFacets?
     - add hierarchy to ssdv facets?
     - sparse faceting: allow skipping of certain dims?

Modified: lucene/dev/branches/lucene5339/lucene/demo/src/java/org/apache/lucene/demo/facet/DistanceFacetsExample.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/demo/src/java/org/apache/lucene/demo/facet/DistanceFacetsExample.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/demo/src/java/org/apache/lucene/demo/facet/DistanceFacetsExample.java (original)
+++ lucene/dev/branches/lucene5339/lucene/demo/src/java/org/apache/lucene/demo/facet/DistanceFacetsExample.java Mon Dec  2 23:44:13 2013
@@ -20,14 +20,11 @@ package org.apache.lucene.demo.facet;
 import java.io.Closeable;
 import java.io.IOException;
 import java.text.ParseException;
-import java.util.List;
 
 import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.DoubleField;
 import org.apache.lucene.document.Field;
-import org.apache.lucene.document.LongField;
-import org.apache.lucene.document.NumericDocValuesField;
 import org.apache.lucene.expressions.Expression;
 import org.apache.lucene.expressions.SimpleBindings;
 import org.apache.lucene.expressions.js.JavascriptCompiler;
@@ -37,14 +34,13 @@ import org.apache.lucene.facet.DrillDown
 import org.apache.lucene.facet.FacetResult;
 import org.apache.lucene.facet.Facets;
 import org.apache.lucene.facet.FacetsCollector;
-import org.apache.lucene.facet.FacetsConfig;
-import org.apache.lucene.facet.LongRange;
 import org.apache.lucene.index.DirectoryReader;
 import org.apache.lucene.index.IndexWriter;
 import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.search.ConstantScoreQuery;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.MatchAllDocsQuery;
-import org.apache.lucene.search.NumericRangeQuery;
 import org.apache.lucene.search.SortField;
 import org.apache.lucene.search.TopDocs;
 import org.apache.lucene.store.Directory;
@@ -56,6 +52,11 @@ import org.apache.lucene.store.RAMDirect
  *  expressions module to calculate distance. */
 public class DistanceFacetsExample implements Closeable {
 
+  final DoubleRange ONE_KM = new DoubleRange("< 1 km", 0.0, true, 1.0, false);
+  final DoubleRange TWO_KM = new DoubleRange("< 2 km", 0.0, true, 2.0, false);
+  final DoubleRange FIVE_KM = new DoubleRange("< 5 km", 0.0, true, 5.0, false);
+  final DoubleRange TEN_KM = new DoubleRange("< 10 km", 0.0, true, 10.0, false);
+
   private final Directory indexDir = new RAMDirectory();
   private IndexSearcher searcher;
 
@@ -88,9 +89,7 @@ public class DistanceFacetsExample imple
     writer.close();
   }
 
-  /** User runs a query and counts facets. */
-  public FacetResult search() throws IOException {
-
+  private ValueSource getDistanceValueSource() {
     Expression distance;
     try {
       distance = JavascriptCompiler.compile("haversin(40.7143528,-74.0059731,latitude,longitude)");
@@ -102,22 +101,37 @@ public class DistanceFacetsExample imple
     bindings.add(new SortField("latitude", SortField.Type.DOUBLE));
     bindings.add(new SortField("longitude", SortField.Type.DOUBLE));
 
+    return distance.getValueSource(bindings);
+  }
+
+  /** User runs a query and counts facets. */
+  public FacetResult search() throws IOException {
+
+
     FacetsCollector fc = new FacetsCollector();
 
     searcher.search(new MatchAllDocsQuery(), fc);
 
-    Facets facets = new DoubleRangeFacetCounts("field", distance.getValueSource(bindings), fc,
-        new DoubleRange("< 1 km", 0.0, true, 1.0, false),
-        new DoubleRange("< 2 km", 0.0, true, 2.0, false),
-        new DoubleRange("< 5 km", 0.0, true, 5.0, false),
-        new DoubleRange("< 10 km", 0.0, true, 10.0, false),
-        new DoubleRange("< 20 km", 0.0, true, 20.0, false),
-        new DoubleRange("< 50 km", 0.0, true, 50.0, false));
+    Facets facets = new DoubleRangeFacetCounts("field", getDistanceValueSource(), fc,
+                                               ONE_KM,
+                                               TWO_KM,
+                                               FIVE_KM,
+                                               TEN_KM);
 
     return facets.getTopChildren(10, "field");
   }
 
-  // nocommit how to show drillDown?
+  /** User drills down on the specified range. */
+  public TopDocs drillDown(DoubleRange range) throws IOException {
+
+    // Passing no baseQuery means we drill down on all
+    // documents ("browse only"):
+    DrillDownQuery q = new DrillDownQuery(null);
+
+    q.add("field", new ConstantScoreQuery(range.getFilter(getDistanceValueSource())));
+
+    return searcher.search(q, 10);
+  }
 
   @Override
   public void close() throws IOException {
@@ -128,13 +142,19 @@ public class DistanceFacetsExample imple
   /** Runs the search and drill-down examples and prints the results. */
   @SuppressWarnings("unchecked")
   public static void main(String[] args) throws Exception {
-    RangeFacetsExample example = new RangeFacetsExample();
+    DistanceFacetsExample example = new DistanceFacetsExample();
     example.index();
 
-    System.out.println("Dirance facet counting example:");
+    System.out.println("Distance facet counting example:");
     System.out.println("-----------------------");
     System.out.println(example.search());
 
+    System.out.println("\n");
+    System.out.println("Distance facet drill-down example (field/< 2 km):");
+    System.out.println("---------------------------------------------");
+    TopDocs hits = example.drillDown(example.TWO_KM);
+    System.out.println(hits.totalHits + " totalHits");
+
     example.close();
   }
 }

Modified: lucene/dev/branches/lucene5339/lucene/demo/src/java/org/apache/lucene/demo/facet/RangeFacetsExample.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/demo/src/java/org/apache/lucene/demo/facet/RangeFacetsExample.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/demo/src/java/org/apache/lucene/demo/facet/RangeFacetsExample.java (original)
+++ lucene/dev/branches/lucene5339/lucene/demo/src/java/org/apache/lucene/demo/facet/RangeFacetsExample.java Mon Dec  2 23:44:13 2013
@@ -19,7 +19,6 @@ package org.apache.lucene.demo.facet;
 
 import java.io.Closeable;
 import java.io.IOException;
-import java.util.List;
 
 import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
 import org.apache.lucene.document.Document;
@@ -110,8 +109,6 @@ public class RangeFacetsExample implemen
     // documents ("browse only"):
     DrillDownQuery q = new DrillDownQuery(getConfig());
 
-    // Use FieldCacheRangeFilter; this will use
-    // NumericDocValues:
     q.add("timestamp", NumericRangeQuery.newLongRange("timestamp", range.min, range.max, range.minInclusive, range.maxInclusive));
 
     return searcher.search(q, 10);

Modified: lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAssociationsFacetsExample.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAssociationsFacetsExample.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAssociationsFacetsExample.java (original)
+++ lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestAssociationsFacetsExample.java Mon Dec  2 23:44:13 2013
@@ -29,7 +29,7 @@ public class TestAssociationsFacetsExamp
   public void testExamples() throws Exception {
     List<FacetResult> res = new AssociationsFacetsExample().runSumAssociations();
     assertEquals("Wrong number of results", 2, res.size());
-    assertEquals("value=-1 childCount=2\n  lucene (4)\n  solr (2)\n", res.get(0).toString());
-    assertEquals("value=-1.0 childCount=2\n  computing (1.62)\n  software (0.34)\n", res.get(1).toString());
+    assertEquals("dim=tags path=[] value=-1 childCount=2\n  lucene (4)\n  solr (2)\n", res.get(0).toString());
+    assertEquals("dim=genre path=[] value=-1.0 childCount=2\n  computing (1.62)\n  software (0.34)\n", res.get(1).toString());
   }  
 }

Modified: lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestDistanceFacetsExample.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestDistanceFacetsExample.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestDistanceFacetsExample.java (original)
+++ lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestDistanceFacetsExample.java Mon Dec  2 23:44:13 2013
@@ -17,7 +17,6 @@ package org.apache.lucene.demo.facet;
  * limitations under the License.
  */
 
-import java.util.List;
 
 import org.apache.lucene.facet.FacetResult;
 import org.apache.lucene.search.TopDocs;
@@ -31,7 +30,15 @@ public class TestDistanceFacetsExample e
     DistanceFacetsExample example = new DistanceFacetsExample();
     example.index();
     FacetResult result = example.search();
-    assertEquals("value=3 childCount=6\n  < 1 km (1)\n  < 2 km (2)\n  < 5 km (2)\n  < 10 km (3)\n  < 20 km (3)\n  < 50 km (3)\n", result.toString());
+    assertEquals("dim=field path=[] value=3 childCount=4\n  < 1 km (1)\n  < 2 km (2)\n  < 5 km (2)\n  < 10 km (3)\n", result.toString());
+    example.close();
+  }
+
+  public void testDrillDown() throws Exception {
+    DistanceFacetsExample example = new DistanceFacetsExample();
+    example.index();
+    TopDocs hits = example.drillDown(example.FIVE_KM);
+    assertEquals(2, hits.totalHits);
     example.close();
   }
 }

Modified: lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestExpressionAggregationFacetsExample.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestExpressionAggregationFacetsExample.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestExpressionAggregationFacetsExample.java (original)
+++ lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestExpressionAggregationFacetsExample.java Mon Dec  2 23:44:13 2013
@@ -29,6 +29,6 @@ public class TestExpressionAggregationFa
   @Test
   public void testSimple() throws Exception {
     FacetResult result = new ExpressionAggregationFacetsExample().runSearch();
-    assertEquals("value=3.9681187 childCount=2\n  B (2.236068)\n  C (1.7320508)\n", result.toString());
+    assertEquals("dim=A path=[] value=3.9681187 childCount=2\n  B (2.236068)\n  C (1.7320508)\n", result.toString());
   }
 }

Modified: lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestMultiCategoryListsFacetsExample.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestMultiCategoryListsFacetsExample.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestMultiCategoryListsFacetsExample.java (original)
+++ lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestMultiCategoryListsFacetsExample.java Mon Dec  2 23:44:13 2013
@@ -29,7 +29,7 @@ public class TestMultiCategoryListsFacet
   public void testExample() throws Exception {
     List<FacetResult> results = new MultiCategoryListsFacetsExample().runSearch();
     assertEquals(2, results.size());
-    assertEquals("value=5 childCount=4\n  Lisa (2)\n  Bob (1)\n  Susan (1)\n  Frank (1)\n", results.get(0).toString());
-    assertEquals("value=5 childCount=3\n  2010 (2)\n  2012 (2)\n  1999 (1)\n", results.get(1).toString());
+    assertEquals("dim=Author path=[] value=5 childCount=4\n  Lisa (2)\n  Bob (1)\n  Susan (1)\n  Frank (1)\n", results.get(0).toString());
+    assertEquals("dim=Publish Date path=[] value=5 childCount=3\n  2010 (2)\n  2012 (2)\n  1999 (1)\n", results.get(1).toString());
   }
 }

Modified: lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestRangeFacetsExample.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestRangeFacetsExample.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestRangeFacetsExample.java (original)
+++ lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestRangeFacetsExample.java Mon Dec  2 23:44:13 2013
@@ -33,7 +33,7 @@ public class TestRangeFacetsExample exte
     RangeFacetsExample example = new RangeFacetsExample();
     example.index();
     FacetResult result = example.search();
-    assertEquals("value=100 childCount=3\n  Past hour (4)\n  Past six hours (22)\n  Past day (87)\n", result.toString());
+    assertEquals("dim=timestamp path=[] value=100 childCount=3\n  Past hour (4)\n  Past six hours (22)\n  Past day (87)\n", result.toString());
     example.close();
   }
 

Modified: lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleFacetsExample.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleFacetsExample.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleFacetsExample.java (original)
+++ lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleFacetsExample.java Mon Dec  2 23:44:13 2013
@@ -30,13 +30,13 @@ public class TestSimpleFacetsExample ext
   public void testSimple() throws Exception {
     List<FacetResult> results = new SimpleFacetsExample().runSearch();
     assertEquals(2, results.size());
-    assertEquals("value=5 childCount=4\n  Lisa (2)\n  Bob (1)\n  Susan (1)\n  Frank (1)\n", results.get(0).toString());
-    assertEquals("value=5 childCount=3\n  2010 (2)\n  2012 (2)\n  1999 (1)\n", results.get(1).toString());
+    assertEquals("dim=Author path=[] value=5 childCount=4\n  Lisa (2)\n  Bob (1)\n  Susan (1)\n  Frank (1)\n", results.get(0).toString());
+    assertEquals("dim=Publish Date path=[] value=5 childCount=3\n  2010 (2)\n  2012 (2)\n  1999 (1)\n", results.get(1).toString());
   }
 
   @Test
   public void testDrillDown() throws Exception {
     FacetResult result = new SimpleFacetsExample().runDrillDown();
-    assertEquals("value=2 childCount=2\n  Bob (1)\n  Lisa (1)\n", result.toString());
+    assertEquals("dim=Author path=[] value=2 childCount=2\n  Bob (1)\n  Lisa (1)\n", result.toString());
   }
 }

Modified: lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleSortedSetFacetsExample.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleSortedSetFacetsExample.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleSortedSetFacetsExample.java (original)
+++ lucene/dev/branches/lucene5339/lucene/demo/src/test/org/apache/lucene/demo/facet/TestSimpleSortedSetFacetsExample.java Mon Dec  2 23:44:13 2013
@@ -34,13 +34,13 @@ public class TestSimpleSortedSetFacetsEx
   public void testSimple() throws Exception {
     List<FacetResult> results = new SimpleSortedSetFacetsExample().runSearch();
     assertEquals(2, results.size());
-    assertEquals("value=5 childCount=4\n  Lisa (2)\n  Bob (1)\n  Frank (1)\n  Susan (1)\n", results.get(0).toString());
-    assertEquals("value=5 childCount=3\n  2010 (2)\n  2012 (2)\n  1999 (1)\n", results.get(1).toString());
+    assertEquals("dim=Author path=[] value=5 childCount=4\n  Lisa (2)\n  Bob (1)\n  Frank (1)\n  Susan (1)\n", results.get(0).toString());
+    assertEquals("dim=Publish Year path=[] value=5 childCount=3\n  2010 (2)\n  2012 (2)\n  1999 (1)\n", results.get(1).toString());
   }
 
   @Test
   public void testDrillDown() throws Exception {
     FacetResult result = new SimpleSortedSetFacetsExample().runDrillDown();
-    assertEquals("value=2 childCount=2\n  Bob (1)\n  Lisa (1)\n", result.toString());
+    assertEquals("dim=Author path=[] value=2 childCount=2\n  Bob (1)\n  Lisa (1)\n", result.toString());
   }
 }

Modified: lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/DoubleRange.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/DoubleRange.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/DoubleRange.java (original)
+++ lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/DoubleRange.java Mon Dec  2 23:44:13 2013
@@ -17,7 +17,17 @@ package org.apache.lucene.facet;
  * limitations under the License.
  */
 
+import java.io.IOException;
+import java.util.Collections;
+
 import org.apache.lucene.document.DoubleDocValuesField; // javadocs
+import org.apache.lucene.index.AtomicReaderContext;
+import org.apache.lucene.queries.function.FunctionValues;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.search.DocIdSet;
+import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.Filter;
+import org.apache.lucene.util.Bits;
 
 /** Represents a range over double values. */
 public final class DoubleRange extends Range {
@@ -64,5 +74,73 @@ public final class DoubleRange extends R
   public boolean accept(double value) {
     return value >= minIncl && value <= maxIncl;
   }
+
+  /** Returns a new {@link Filter} accepting only documents
+   *  in this range.  Note that this filter is not
+   *  efficient: it's a linear scan of all docs, testing
+   *  each value.  If the {@link ValueSource} is static,
+   *  e.g. an indexed numeric field, then it's more
+   *  efficient to use {@link NumericRangeFilter}. */
+  public Filter getFilter(final ValueSource valueSource) {
+    return new Filter() {
+      @Override
+      public DocIdSet getDocIdSet(AtomicReaderContext context, final Bits acceptDocs) throws IOException {
+
+        // TODO: this is just like ValueSourceScorer,
+        // ValueSourceFilter (spatial),
+        // ValueSourceRangeFilter (solr); also,
+        // https://issues.apache.org/jira/browse/LUCENE-4251
+
+        final FunctionValues values = valueSource.getValues(Collections.emptyMap(), context);
+
+        final int maxDoc = context.reader().maxDoc();
+
+        return new DocIdSet() {
+
+          @Override
+          public DocIdSetIterator iterator() {
+            return new DocIdSetIterator() {
+              int doc = -1;
+
+              @Override
+              public int nextDoc() throws IOException {
+                while (true) {
+                  doc++;
+                  if (doc == maxDoc) {
+                    return doc = NO_MORE_DOCS;
+                  }
+                  if (acceptDocs != null && acceptDocs.get(doc) == false) {
+                    continue;
+                  }
+                  double v = values.doubleVal(doc);
+                  if (accept(v)) {
+                    return doc;
+                  }
+                }
+              }
+
+              @Override
+              public int advance(int target) throws IOException {
+                doc = target-1;
+                return nextDoc();
+              }
+
+              @Override
+              public int docID() {
+                return doc;
+              }
+
+              @Override
+              public long cost() {
+                // Since we do a linear scan over all
+                // documents, our cost is O(maxDoc):
+                return maxDoc;
+              }
+            };
+          }
+        };
+      }
+    };
+  }
 }
 

Modified: lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/DoubleRangeFacetCounts.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/DoubleRangeFacetCounts.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/DoubleRangeFacetCounts.java (original)
+++ lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/DoubleRangeFacetCounts.java Mon Dec  2 23:44:13 2013
@@ -24,7 +24,6 @@ import java.util.List;
 import org.apache.lucene.document.DoubleDocValuesField; // javadocs
 import org.apache.lucene.document.FloatDocValuesField; // javadocs
 import org.apache.lucene.facet.FacetsCollector.MatchingDocs;
-import org.apache.lucene.facet.taxonomy.FacetLabel;
 import org.apache.lucene.queries.function.FunctionValues;
 import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.queries.function.valuesource.DoubleFieldSource;
@@ -108,13 +107,16 @@ public class DoubleRangeFacetCounts exte
     if (dim.equals(field) == false) {
       throw new IllegalArgumentException("invalid dim \"" + dim + "\"; should be \"" + field + "\"");
     }
+    if (path.length != 0) {
+      throw new IllegalArgumentException("path.length should be 0");
+    }
     LabelAndValue[] labelValues = new LabelAndValue[counts.length];
     for(int i=0;i<counts.length;i++) {
       // nocommit can we add the range into this?
       labelValues[i] = new LabelAndValue(ranges[i].label, counts[i]);
     }
 
-    return new FacetResult(totCount, labelValues, labelValues.length);
+    return new FacetResult(dim, path, totCount, labelValues, labelValues.length);
   }
 
   @Override

Modified: lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/FacetResult.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/FacetResult.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/FacetResult.java (original)
+++ lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/FacetResult.java Mon Dec  2 23:44:13 2013
@@ -18,10 +18,15 @@ package org.apache.lucene.facet;
  */
 
 import java.util.Arrays;
-import java.util.List;
 
 public final class FacetResult {
 
+  /** Dimension that was requested. */
+  public final String dim;
+
+  /** Path whose children were requested. */
+  public final String[] path;
+
   /** Total value for this path (sum of all child counts, or
    *  sum of all child values), even those not included in
    *  the topN. */
@@ -33,7 +38,9 @@ public final class FacetResult {
   /** Child counts. */
   public final LabelAndValue[] labelValues;
 
-  public FacetResult(Number value, LabelAndValue[] labelValues, int childCount) {
+  public FacetResult(String dim, String[] path, Number value, LabelAndValue[] labelValues, int childCount) {
+    this.dim = dim;
+    this.path = path;
     this.value = value;
     this.labelValues = labelValues;
     this.childCount = childCount;
@@ -42,7 +49,11 @@ public final class FacetResult {
   @Override
   public String toString() {
     StringBuilder sb = new StringBuilder();
-    sb.append("value=");
+    sb.append("dim=");
+    sb.append(dim);
+    sb.append(" path=");
+    sb.append(Arrays.toString(path));
+    sb.append(" value=");
     sb.append(value);
     sb.append(" childCount=");
     sb.append(childCount);

Modified: lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/FloatTaxonomyFacets.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/FloatTaxonomyFacets.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/FloatTaxonomyFacets.java (original)
+++ lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/FloatTaxonomyFacets.java Mon Dec  2 23:44:13 2013
@@ -131,6 +131,6 @@ public abstract class FloatTaxonomyFacet
       labelValues[i] = new LabelAndValue(child.components[cp.length], ordAndValue.value);
     }
 
-    return new FacetResult(sumValues, labelValues, childCount);
+    return new FacetResult(dim, path, sumValues, labelValues, childCount);
   }
 }
\ No newline at end of file

Modified: lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/IntTaxonomyFacets.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/IntTaxonomyFacets.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/IntTaxonomyFacets.java (original)
+++ lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/IntTaxonomyFacets.java Mon Dec  2 23:44:13 2013
@@ -135,6 +135,6 @@ public abstract class IntTaxonomyFacets 
       labelValues[i] = new LabelAndValue(child.components[cp.length], ordAndValue.value);
     }
 
-    return new FacetResult(totValue, labelValues, childCount);
+    return new FacetResult(dim, path, totValue, labelValues, childCount);
   }
 }
\ No newline at end of file

Modified: lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/LongRange.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/LongRange.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/LongRange.java (original)
+++ lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/LongRange.java Mon Dec  2 23:44:13 2013
@@ -17,7 +17,17 @@ package org.apache.lucene.facet;
  * limitations under the License.
  */
 
+import java.io.IOException;
+import java.util.Collections;
+
 import org.apache.lucene.document.NumericDocValuesField; // javadocs
+import org.apache.lucene.index.AtomicReaderContext;
+import org.apache.lucene.queries.function.FunctionValues;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.search.DocIdSet;
+import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.Filter;
+import org.apache.lucene.util.Bits;
 
 /** Represents a range over long values. */
 public final class LongRange extends Range {
@@ -55,4 +65,72 @@ public final class LongRange extends Ran
   public boolean accept(long value) {
     return value >= minIncl && value <= maxIncl;
   }
+
+  /** Returns a new {@link Filter} accepting only documents
+   *  in this range.  Note that this filter is not
+   *  efficient: it's a linear scan of all docs, testing
+   *  each value.  If the {@link ValueSource} is static,
+   *  e.g. an indexed numeric field, then it's more
+   *  efficient to use {@link NumericRangeFilter}. */
+  public Filter getFilter(final ValueSource valueSource) {
+    return new Filter() {
+      @Override
+      public DocIdSet getDocIdSet(AtomicReaderContext context, final Bits acceptDocs) throws IOException {
+
+        // TODO: this is just like ValueSourceScorer,
+        // ValueSourceFilter (spatial),
+        // ValueSourceRangeFilter (solr); also,
+        // https://issues.apache.org/jira/browse/LUCENE-4251
+
+        final FunctionValues values = valueSource.getValues(Collections.emptyMap(), context);
+
+        final int maxDoc = context.reader().maxDoc();
+
+        return new DocIdSet() {
+
+          @Override
+          public DocIdSetIterator iterator() {
+            return new DocIdSetIterator() {
+              int doc = -1;
+
+              @Override
+              public int nextDoc() throws IOException {
+                while (true) {
+                  doc++;
+                  if (doc == maxDoc) {
+                    return doc = NO_MORE_DOCS;
+                  }
+                  if (acceptDocs != null && acceptDocs.get(doc) == false) {
+                    continue;
+                  }
+                  long v = values.longVal(doc);
+                  if (accept(v)) {
+                    return doc;
+                  }
+                }
+              }
+
+              @Override
+              public int advance(int target) throws IOException {
+                doc = target-1;
+                return nextDoc();
+              }
+
+              @Override
+              public int docID() {
+                return doc;
+              }
+
+              @Override
+              public long cost() {
+                // Since we do a linear scan over all
+                // documents, our cost is O(maxDoc):
+                return maxDoc;
+              }
+            };
+          }
+        };
+      }
+    };
+  }
 }

Modified: lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/LongRangeFacetCounts.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/LongRangeFacetCounts.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/LongRangeFacetCounts.java (original)
+++ lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/LongRangeFacetCounts.java Mon Dec  2 23:44:13 2013
@@ -22,7 +22,6 @@ import java.util.Collections;
 import java.util.List;
 
 import org.apache.lucene.facet.FacetsCollector.MatchingDocs;
-import org.apache.lucene.facet.taxonomy.FacetLabel;
 import org.apache.lucene.queries.function.FunctionValues;
 import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.queries.function.valuesource.LongFieldSource;
@@ -98,13 +97,16 @@ public class LongRangeFacetCounts extend
     if (dim.equals(field) == false) {
       throw new IllegalArgumentException("invalid dim \"" + dim + "\"; should be \"" + field + "\"");
     }
+    if (path.length != 0) {
+      throw new IllegalArgumentException("path.length should be 0");
+    }
     LabelAndValue[] labelValues = new LabelAndValue[counts.length];
     for(int i=0;i<counts.length;i++) {
       // nocommit can we add the range into this?
       labelValues[i] = new LabelAndValue(ranges[i].label, counts[i]);
     }
 
-    return new FacetResult(totCount, labelValues, labelValues.length);
+    return new FacetResult(dim, path, totCount, labelValues, labelValues.length);
   }
 
   @Override

Modified: lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/SortedSetDocValuesFacetCounts.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/SortedSetDocValuesFacetCounts.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/SortedSetDocValuesFacetCounts.java (original)
+++ lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/SortedSetDocValuesFacetCounts.java Mon Dec  2 23:44:13 2013
@@ -19,17 +19,13 @@ package org.apache.lucene.facet;
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.lucene.facet.FacetsCollector.MatchingDocs;
 import org.apache.lucene.facet.SortedSetDocValuesReaderState.OrdRange;
-import org.apache.lucene.facet.SortedSetDocValuesReaderState;
-import org.apache.lucene.facet.taxonomy.FacetLabel;
 import org.apache.lucene.index.AtomicReader;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.MultiDocValues.MultiSortedSetDocValues;
@@ -37,7 +33,6 @@ import org.apache.lucene.index.MultiDocV
 import org.apache.lucene.index.ReaderUtil;
 import org.apache.lucene.index.SortedSetDocValues;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.PriorityQueue;
 
 /** Compute facets counts from previously
  *  indexed {@link SortedSetDocValuesFacetField},
@@ -51,8 +46,11 @@ import org.apache.lucene.util.PriorityQu
  *
  *  <p><b>NOTE</b>: this class should be instantiated and
  *  then used from a single thread, because it holds a
- *  thread-private instance of {@link SortedSetDocValues}. */
-
+ *  thread-private instance of {@link SortedSetDocValues}.
+ * 
+ * <p><b>NOTE:<b/>: tie-break is by unicode sort order
+ *
+ * @lucene.experimental */
 public class SortedSetDocValuesFacetCounts extends Facets {
 
   final SortedSetDocValuesReaderState state;
@@ -136,7 +134,7 @@ public class SortedSetDocValuesFacetCoun
       labelValues[i] = new LabelAndValue(parts[1], ordAndValue.value);
     }
 
-    return new FacetResult(dimCount, labelValues, childCount);
+    return new FacetResult(dim, new String[0], dimCount, labelValues, childCount);
   }
 
   /** Does all the "real work" of tallying up the counts. */
@@ -283,7 +281,7 @@ public class SortedSetDocValuesFacetCoun
                          } else if (b.value.intValue() > a.value.intValue()) {
                            return 1;
                          } else {
-                           return 0;
+                           return a.dim.compareTo(b.dim);
                          }
                        }
                      });

Modified: lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/TaxonomyFacets.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/TaxonomyFacets.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/TaxonomyFacets.java (original)
+++ lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/TaxonomyFacets.java Mon Dec  2 23:44:13 2013
@@ -77,11 +77,10 @@ public abstract class TaxonomyFacets ext
                          } else if (b.value.doubleValue() > a.value.doubleValue()) {
                            return 1;
                          } else {
-                           return 0;
+                           return a.dim.compareTo(b.dim);
                          }
                        }
                      });
-
     return results;
   }
 }
\ No newline at end of file

Modified: lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/FacetLabel.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/FacetLabel.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/FacetLabel.java (original)
+++ lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/FacetLabel.java Mon Dec  2 23:44:13 2013
@@ -42,7 +42,7 @@ public class FacetLabel implements Compa
   public final static int MAX_CATEGORY_PATH_LENGTH = (BYTE_BLOCK_SIZE - 2) / 4;
 
   /** An empty {@link FacetLabel} */
-  public static final FacetLabel EMPTY = new FacetLabel();
+  //public static final FacetLabel EMPTY = new FacetLabel();
 
   /**
    * The components of this {@link FacetLabel}. Note that this array may be
@@ -66,7 +66,7 @@ public class FacetLabel implements Compa
     // while the code which calls this method is safe, at some point a test
     // tripped on AIOOBE in toString, but we failed to reproduce. adding the
     // assert as a safety check.
-    assert prefixLen > 0 && prefixLen <= copyFrom.components.length : 
+    assert prefixLen >= 0 && prefixLen <= copyFrom.components.length : 
       "prefixLen cannot be negative nor larger than the given components' length: prefixLen=" + prefixLen
         + " components.length=" + copyFrom.components.length;
     this.components = copyFrom.components;
@@ -90,8 +90,6 @@ public class FacetLabel implements Compa
   }
 
   private void checkComponents() {
-    // nocommit why so anal?
-    // assert components.length > 0 : "use CategoryPath.EMPTY to create an empty path";
     long len = 0;
     for (String comp : components) {
       if (comp == null || comp.isEmpty()) {
@@ -158,25 +156,10 @@ public class FacetLabel implements Compa
     return hash;
   }
 
-  /** Calculate a 64-bit hash function for this path. */
-  public long longHashCode() {
-    if (length == 0) {
-      return 0;
-    }
-    
-    long hash = length;
-    for (int i = 0; i < length; i++) {
-      hash = hash * 65599 + components[i].hashCode();
-    }
-    return hash;
-  }
-
   /** Returns a sub-path of this path up to {@code length} components. */
   public FacetLabel subpath(final int length) {
     if (length >= this.length || length < 0) {
       return this;
-    } else if (length == 0) {
-      return EMPTY;
     } else {
       return new FacetLabel(this, length);
     }

Modified: lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyWriter.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyWriter.java (original)
+++ lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyWriter.java Mon Dec  2 23:44:13 2013
@@ -231,7 +231,7 @@ public class DirectoryTaxonomyWriter imp
       cacheIsComplete = true;
       // Make sure that the taxonomy always contain the root category
       // with category id 0.
-      addCategory(FacetLabel.EMPTY);
+      addCategory(new FacetLabel());
     } else {
       // There are some categories on the disk, which we have not yet
       // read into the cache, and therefore the cache is incomplete.

Modified: lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/writercache/CompactLabelToOrdinal.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/writercache/CompactLabelToOrdinal.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/writercache/CompactLabelToOrdinal.java (original)
+++ lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/writercache/CompactLabelToOrdinal.java Mon Dec  2 23:44:13 2013
@@ -101,7 +101,7 @@ public class CompactLabelToOrdinal exten
 
   private void init() {
     labelRepository = new CharBlockArray();
-    CategoryPathUtils.serialize(FacetLabel.EMPTY, labelRepository);
+    CategoryPathUtils.serialize(new FacetLabel(), labelRepository);
 
     int c = this.capacity;
     for (int i = 0; i < this.hashArrays.length; i++) {

Modified: lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/writercache/NameHashIntCacheLRU.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/writercache/NameHashIntCacheLRU.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/writercache/NameHashIntCacheLRU.java (original)
+++ lucene/dev/branches/lucene5339/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/writercache/NameHashIntCacheLRU.java Mon Dec  2 23:44:13 2013
@@ -36,12 +36,12 @@ public class NameHashIntCacheLRU extends
 
   @Override
   Object key(FacetLabel name) {
-    return new Long(name.longHashCode());
+    return new Integer(name.hashCode());
   }
 
   @Override
   Object key(FacetLabel name, int prefixLen) {
-    return new Long(name.subpath(prefixLen).longHashCode());
+    return new Integer(name.subpath(prefixLen).hashCode());
   }
   
 }

Modified: lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/FacetTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/FacetTestCase.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/FacetTestCase.java (original)
+++ lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/FacetTestCase.java Mon Dec  2 23:44:13 2013
@@ -18,10 +18,19 @@ package org.apache.lucene.facet;
  */
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.Random;
 
 import org.apache.lucene.facet.taxonomy.TaxonomyReader;
+import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util._TestUtil;
 
 public abstract class FacetTestCase extends LuceneTestCase {
   
@@ -43,4 +52,154 @@ public abstract class FacetTestCase exte
 
     return facets;
   }
+
+  protected String[] getRandomTokens(int count) {
+    String[] tokens = new String[count];
+    for(int i=0;i<tokens.length;i++) {
+      tokens[i] = _TestUtil.randomRealisticUnicodeString(random(), 1, 10);
+      //tokens[i] = _TestUtil.randomSimpleString(random(), 1, 10);
+    }
+    return tokens;
+  }
+
+  protected String pickToken(String[] tokens) {
+    for(int i=0;i<tokens.length;i++) {
+      if (random().nextBoolean()) {
+        return tokens[i];
+      }
+    }
+
+    // Move long tail onto first token:
+    return tokens[0];
+  }
+
+  protected static class TestDoc {
+    public String content;
+    public String[] dims;
+    public float value;
+  }
+
+  protected List<TestDoc> getRandomDocs(String[] tokens, int count, int numDims) {
+    List<TestDoc> docs = new ArrayList<>();
+    for(int i=0;i<count;i++) {
+      TestDoc doc = new TestDoc();
+      docs.add(doc);
+      doc.content = pickToken(tokens);
+      doc.dims = new String[numDims];
+      for(int j=0;j<numDims;j++) {
+        doc.dims[j] = pickToken(tokens);
+        if (random().nextInt(10) < 3) {
+          break;
+        }
+      }
+      if (VERBOSE) {
+        System.out.println("  doc " + i + ": content=" + doc.content);
+        for(int j=0;j<numDims;j++) {
+          if (doc.dims[j] != null) {
+            System.out.println("    dim[" + j + "]=" + doc.dims[j]);
+          }
+        }
+      }
+    }
+
+    return docs;
+  }
+  
+  protected void sortTies(List<FacetResult> results) {
+    for(FacetResult result : results) {
+      sortTies(result.labelValues);
+    }
+  }
+
+  protected void sortTies(LabelAndValue[] labelValues) {
+    double lastValue = -1;
+    int numInRow = 0;
+    int i = 0;
+    while(i <= labelValues.length) {
+      if (i < labelValues.length && labelValues[i].value.doubleValue() == lastValue) {
+        numInRow++;
+      } else {
+        if (numInRow > 1) {
+          Arrays.sort(labelValues, i-numInRow, i,
+                      new Comparator<LabelAndValue>() {
+                        @Override
+                        public int compare(LabelAndValue a, LabelAndValue b) {
+                          assert a.value.doubleValue() == b.value.doubleValue();
+                          return new BytesRef(a.label).compareTo(new BytesRef(b.label));
+                        }
+                      });
+        }
+        numInRow = 1;
+        if (i < labelValues.length) {
+          lastValue = labelValues[i].value.doubleValue();
+        }
+      }
+      i++;
+    }
+  }
+
+  protected void sortLabelValues(List<LabelAndValue> labelValues) {
+    Collections.sort(labelValues,
+                     new Comparator<LabelAndValue>() {
+                       @Override
+                       public int compare(LabelAndValue a, LabelAndValue b) {
+                         if (a.value.doubleValue() > b.value.doubleValue()) {
+                           return -1;
+                         } else if (a.value.doubleValue() < b.value.doubleValue()) {
+                           return 1;
+                         } else {
+                           return new BytesRef(a.label).compareTo(new BytesRef(b.label));
+                         }
+                       }
+                     });
+  }
+
+  protected void sortFacetResults(List<FacetResult> results) {
+      Collections.sort(results,
+                       new Comparator<FacetResult>() {
+                         @Override
+                         public int compare(FacetResult a, FacetResult b) {
+                           if (a.value.doubleValue() > b.value.doubleValue()) {
+                             return -1;
+                           } else if (b.value.doubleValue() > a.value.doubleValue()) {
+                             return 1;
+                           } else {
+                             return 0;
+                           }
+                         }
+                       });
+  }
+
+  protected void assertFloatValuesEquals(List<FacetResult> a, List<FacetResult> b) {
+    assertEquals(a.size(), b.size());
+    float lastValue = Float.POSITIVE_INFINITY;
+    Map<String,FacetResult> aByDim = new HashMap<String,FacetResult>();
+    for(int i=0;i<a.size();i++) {
+      assertTrue(a.get(i).value.floatValue() <= lastValue);
+      lastValue = a.get(i).value.floatValue();
+      aByDim.put(a.get(i).dim, a.get(i));
+    }
+    lastValue = Float.POSITIVE_INFINITY;
+    Map<String,FacetResult> bByDim = new HashMap<String,FacetResult>();
+    for(int i=0;i<b.size();i++) {
+      bByDim.put(b.get(i).dim, b.get(i));
+      assertTrue(b.get(i).value.floatValue() <= lastValue);
+      lastValue = b.get(i).value.floatValue();
+    }
+    for(String dim : aByDim.keySet()) {
+      assertFloatValuesEquals(aByDim.get(dim), bByDim.get(dim));
+    }
+  }
+
+  protected void assertFloatValuesEquals(FacetResult a, FacetResult b) {
+    assertEquals(a.dim, b.dim);
+    assertTrue(Arrays.equals(a.path, b.path));
+    assertEquals(a.childCount, b.childCount);
+    assertEquals(a.value.floatValue(), b.value.floatValue(), a.value.floatValue()/1e5);
+    assertEquals(a.labelValues.length, b.labelValues.length);
+    for(int i=0;i<a.labelValues.length;i++) {
+      assertEquals(a.labelValues[i].label, b.labelValues[i].label);
+      assertEquals(a.labelValues[i].value.floatValue(), b.labelValues[i].value.floatValue(), a.labelValues[i].value.floatValue()/1e5);
+    }
+  }
 }

Modified: lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java (original)
+++ lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java Mon Dec  2 23:44:13 2013
@@ -31,7 +31,6 @@ import org.apache.lucene.analysis.MockAn
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.StringField;
-import org.apache.lucene.facet.FacetTestCase;
 import org.apache.lucene.facet.DrillSideways.DrillSidewaysResult;
 import org.apache.lucene.facet.taxonomy.TaxonomyReader;
 import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader;
@@ -121,12 +120,12 @@ public class TestDrillSideways extends F
     assertEquals(2, r.hits.totalHits);
     // Publish Date is only drill-down, and Lisa published
     // one in 2012 and one in 2010:
-    assertEquals("value=2 childCount=2\n  2010 (1)\n  2012 (1)\n", r.facets.getTopChildren(10, "Publish Date").toString());
+    assertEquals("dim=Publish Date path=[] value=2 childCount=2\n  2010 (1)\n  2012 (1)\n", r.facets.getTopChildren(10, "Publish Date").toString());
 
     // Author is drill-sideways + drill-down: Lisa
     // (drill-down) published twice, and Frank/Susan/Bob
     // published once:
-    assertEquals("value=5 childCount=4\n  Lisa (2)\n  Bob (1)\n  Susan (1)\n  Frank (1)\n", r.facets.getTopChildren(10, "Author").toString());
+    assertEquals("dim=Author path=[] value=5 childCount=4\n  Lisa (2)\n  Bob (1)\n  Susan (1)\n  Frank (1)\n", r.facets.getTopChildren(10, "Author").toString());
 
     // Same simple case, but no baseQuery (pure browse):
     // drill-down on a single field; in this case the
@@ -139,12 +138,12 @@ public class TestDrillSideways extends F
     assertEquals(2, r.hits.totalHits);
     // Publish Date is only drill-down, and Lisa published
     // one in 2012 and one in 2010:
-    assertEquals("value=2 childCount=2\n  2010 (1)\n  2012 (1)\n", r.facets.getTopChildren(10, "Publish Date").toString());
+    assertEquals("dim=Publish Date path=[] value=2 childCount=2\n  2010 (1)\n  2012 (1)\n", r.facets.getTopChildren(10, "Publish Date").toString());
 
     // Author is drill-sideways + drill-down: Lisa
     // (drill-down) published twice, and Frank/Susan/Bob
     // published once:
-    assertEquals("value=5 childCount=4\n  Lisa (2)\n  Bob (1)\n  Susan (1)\n  Frank (1)\n", r.facets.getTopChildren(10, "Author").toString());
+    assertEquals("dim=Author path=[] value=5 childCount=4\n  Lisa (2)\n  Bob (1)\n  Susan (1)\n  Frank (1)\n", r.facets.getTopChildren(10, "Author").toString());
 
     // Another simple case: drill-down on on single fields
     // but OR of two values
@@ -155,11 +154,11 @@ public class TestDrillSideways extends F
     assertEquals(3, r.hits.totalHits);
     // Publish Date is only drill-down: Lisa and Bob
     // (drill-down) published twice in 2010 and once in 2012:
-    assertEquals("value=3 childCount=2\n  2010 (2)\n  2012 (1)\n", r.facets.getTopChildren(10, "Publish Date").toString());
+    assertEquals("dim=Publish Date path=[] value=3 childCount=2\n  2010 (2)\n  2012 (1)\n", r.facets.getTopChildren(10, "Publish Date").toString());
     // Author is drill-sideways + drill-down: Lisa
     // (drill-down) published twice, and Frank/Susan/Bob
     // published once:
-    assertEquals("value=5 childCount=4\n  Lisa (2)\n  Bob (1)\n  Susan (1)\n  Frank (1)\n", r.facets.getTopChildren(10, "Author").toString());
+    assertEquals("dim=Author path=[] value=5 childCount=4\n  Lisa (2)\n  Bob (1)\n  Susan (1)\n  Frank (1)\n", r.facets.getTopChildren(10, "Author").toString());
 
     // More interesting case: drill-down on two fields
     ddq = new DrillDownQuery(config);
@@ -169,10 +168,10 @@ public class TestDrillSideways extends F
     assertEquals(1, r.hits.totalHits);
     // Publish Date is drill-sideways + drill-down: Lisa
     // (drill-down) published once in 2010 and once in 2012:
-    assertEquals("value=2 childCount=2\n  2010 (1)\n  2012 (1)\n", r.facets.getTopChildren(10, "Publish Date").toString());
+    assertEquals("dim=Publish Date path=[] value=2 childCount=2\n  2010 (1)\n  2012 (1)\n", r.facets.getTopChildren(10, "Publish Date").toString());
     // Author is drill-sideways + drill-down:
     // only Lisa & Bob published (once each) in 2010:
-    assertEquals("value=2 childCount=2\n  Bob (1)\n  Lisa (1)\n", r.facets.getTopChildren(10, "Author").toString());
+    assertEquals("dim=Author path=[] value=2 childCount=2\n  Bob (1)\n  Lisa (1)\n", r.facets.getTopChildren(10, "Author").toString());
 
     // Even more interesting case: drill down on two fields,
     // but one of them is OR
@@ -186,10 +185,10 @@ public class TestDrillSideways extends F
     assertEquals(2, r.hits.totalHits);
     // Publish Date is both drill-sideways + drill-down:
     // Lisa or Bob published twice in 2010 and once in 2012:
-    assertEquals("value=3 childCount=2\n  2010 (2)\n  2012 (1)\n", r.facets.getTopChildren(10, "Publish Date").toString());
+    assertEquals("dim=Publish Date path=[] value=3 childCount=2\n  2010 (2)\n  2012 (1)\n", r.facets.getTopChildren(10, "Publish Date").toString());
     // Author is drill-sideways + drill-down:
     // only Lisa & Bob published (once each) in 2010:
-    assertEquals("value=2 childCount=2\n  Bob (1)\n  Lisa (1)\n", r.facets.getTopChildren(10, "Author").toString());
+    assertEquals("dim=Author path=[] value=2 childCount=2\n  Bob (1)\n  Lisa (1)\n", r.facets.getTopChildren(10, "Author").toString());
 
     // Test drilling down on invalid field:
     ddq = new DrillDownQuery(config);
@@ -207,11 +206,11 @@ public class TestDrillSideways extends F
     assertEquals(2, r.hits.totalHits);
     // Publish Date is only drill-down, and Lisa published
     // one in 2012 and one in 2010:
-    assertEquals("value=2 childCount=2\n  2010 (1)\n  2012 (1)\n", r.facets.getTopChildren(10, "Publish Date").toString());
+    assertEquals("dim=Publish Date path=[] value=2 childCount=2\n  2010 (1)\n  2012 (1)\n", r.facets.getTopChildren(10, "Publish Date").toString());
     // Author is drill-sideways + drill-down: Lisa
     // (drill-down) published twice, and Frank/Susan/Bob
     // published once:
-    assertEquals("value=5 childCount=4\n  Lisa (2)\n  Bob (1)\n  Susan (1)\n  Frank (1)\n", r.facets.getTopChildren(10, "Author").toString());
+    assertEquals("dim=Author path=[] value=5 childCount=4\n  Lisa (2)\n  Bob (1)\n  Susan (1)\n  Frank (1)\n", r.facets.getTopChildren(10, "Author").toString());
 
     // LUCENE-4915: test drilling down on a dimension but
     // NOT facet counting it:
@@ -222,7 +221,7 @@ public class TestDrillSideways extends F
     assertEquals(2, r.hits.totalHits);
     // Publish Date is only drill-down, and Lisa published
     // one in 2012 and one in 2010:
-    assertEquals("value=2 childCount=2\n  2010 (1)\n  2012 (1)\n", r.facets.getTopChildren(10, "Publish Date").toString());
+    assertEquals("dim=Publish Date path=[] value=2 childCount=2\n  2010 (1)\n  2012 (1)\n", r.facets.getTopChildren(10, "Publish Date").toString());
 
     // Test main query gets null scorer:
     ddq = new DrillDownQuery(config, new TermQuery(new Term("foobar", "baz")));
@@ -280,11 +279,11 @@ public class TestDrillSideways extends F
     assertEquals(1, r.hits.totalHits);
     // Publish Date is only drill-down, and Lisa published
     // one in 2012 and one in 2010:
-    assertEquals("value=1 childCount=1\n  2010 (1)\n", r.facets.getTopChildren(10, "Publish Date").toString());
+    assertEquals("dim=Publish Date path=[] value=1 childCount=1\n  2010 (1)\n", r.facets.getTopChildren(10, "Publish Date").toString());
     // Author is drill-sideways + drill-down: Lisa
     // (drill-down) published once, and Bob
     // published once:
-    assertEquals("value=2 childCount=2\n  Bob (1)\n  Lisa (1)\n", r.facets.getTopChildren(10, "Author").toString());
+    assertEquals("dim=Author path=[] value=2 childCount=2\n  Bob (1)\n  Lisa (1)\n", r.facets.getTopChildren(10, "Author").toString());
 
     IOUtils.close(searcher.getIndexReader(), taxoReader, writer, taxoWriter, dir, taxoDir);
   }
@@ -338,8 +337,8 @@ public class TestDrillSideways extends F
     DrillSidewaysResult r = new DrillSideways(searcher, config, taxoReader).search(null, ddq, 10);
 
     assertEquals(3, r.hits.totalHits);
-    assertEquals("value=6 childCount=4\n  a (3)\n  b (1)\n  c (1)\n  d (1)\n", r.facets.getTopChildren(10, "dim").toString());
-    assertEquals("value=3 childCount=3\n  x (1)\n  y (1)\n  z (1)\n", r.facets.getTopChildren(10, "dim", "a").toString());
+    assertEquals("dim=dim path=[] value=6 childCount=4\n  a (3)\n  b (1)\n  c (1)\n  d (1)\n", r.facets.getTopChildren(10, "dim").toString());
+    assertEquals("dim=dim path=[a] value=3 childCount=3\n  x (1)\n  y (1)\n  z (1)\n", r.facets.getTopChildren(10, "dim", "a").toString());
 
     IOUtils.close(searcher.getIndexReader(), taxoReader, writer, taxoWriter, dir, taxoDir);
   }

Modified: lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestMultipleIndexFields.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestMultipleIndexFields.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestMultipleIndexFields.java (original)
+++ lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestMultipleIndexFields.java Mon Dec  2 23:44:13 2013
@@ -18,11 +18,7 @@ package org.apache.lucene.facet;
  */
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
 
 import org.apache.lucene.analysis.MockAnalyzer;
@@ -30,8 +26,6 @@ import org.apache.lucene.analysis.MockTo
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.TextField;
-import org.apache.lucene.facet.FacetTestCase;
-import org.apache.lucene.facet.taxonomy.FacetLabel;
 import org.apache.lucene.facet.taxonomy.TaxonomyReader;
 import org.apache.lucene.facet.taxonomy.TaxonomyWriter;
 import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader;
@@ -43,9 +37,6 @@ import org.apache.lucene.index.IndexWrit
 import org.apache.lucene.index.RandomIndexWriter;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.MatchAllDocsQuery;
-import org.apache.lucene.search.MultiCollector;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.TopScoreDocCollector;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.IOUtils;
 import org.junit.Test;
@@ -282,9 +273,9 @@ public class TestMultipleIndexFields ext
 
   private void assertCorrectResults(Facets facets) throws IOException {
     assertEquals(5, facets.getSpecificValue("Band"));
-    assertEquals("value=5 childCount=2\n  Rock & Pop (4)\n  Punk (1)\n", facets.getTopChildren(10, "Band").toString());
-    assertEquals("value=4 childCount=4\n  The Beatles (1)\n  U2 (1)\n  REM (1)\n  Dave Matthews Band (1)\n", facets.getTopChildren(10, "Band", "Rock & Pop").toString());
-    assertEquals("value=3 childCount=3\n  Mark Twain (1)\n  Stephen King (1)\n  Kurt Vonnegut (1)\n", facets.getTopChildren(10, "Author").toString());
+    assertEquals("dim=Band path=[] value=5 childCount=2\n  Rock & Pop (4)\n  Punk (1)\n", facets.getTopChildren(10, "Band").toString());
+    assertEquals("dim=Band path=[Rock & Pop] value=4 childCount=4\n  The Beatles (1)\n  U2 (1)\n  REM (1)\n  Dave Matthews Band (1)\n", facets.getTopChildren(10, "Band", "Rock & Pop").toString());
+    assertEquals("dim=Author path=[] value=3 childCount=3\n  Mark Twain (1)\n  Stephen King (1)\n  Kurt Vonnegut (1)\n", facets.getTopChildren(10, "Author").toString());
   }
 
   private FacetsCollector performSearch(TaxonomyReader tr, IndexReader ir, 

Modified: lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestRangeFacetCounts.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestRangeFacetCounts.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestRangeFacetCounts.java (original)
+++ lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestRangeFacetCounts.java Mon Dec  2 23:44:13 2013
@@ -41,10 +41,10 @@ import org.apache.lucene.queries.functio
 import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
 import org.apache.lucene.queries.function.valuesource.FloatFieldSource;
+import org.apache.lucene.search.ConstantScoreQuery;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.MatchAllDocsQuery;
 import org.apache.lucene.search.NumericRangeQuery;
-import org.apache.lucene.search.SortField;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util._TestUtil;
@@ -80,7 +80,7 @@ public class TestRangeFacetCounts extend
         new LongRange("over 1000", 1000L, false, Long.MAX_VALUE, true));
     
     FacetResult result = facets.getTopChildren(10, "field");
-    assertEquals("value=101 childCount=5\n  less than 10 (10)\n  less than or equal to 10 (11)\n  over 90 (9)\n  90 or above (10)\n  over 1000 (1)\n",
+    assertEquals("dim=field path=[] value=101 childCount=5\n  less than 10 (10)\n  less than or equal to 10 (11)\n  over 90 (9)\n  90 or above (10)\n  over 1000 (1)\n",
                  result.toString());
     
     r.close();
@@ -161,8 +161,8 @@ public class TestRangeFacetCounts extend
     DrillSidewaysResult dsr = ds.search(null, ddq, 10);
 
     assertEquals(100, dsr.hits.totalHits);
-    assertEquals("value=100 childCount=2\n  b (75)\n  a (25)\n", dsr.facets.getTopChildren(10, "dim").toString());
-    assertEquals("value=100 childCount=5\n  less than 10 (10)\n  less than or equal to 10 (11)\n  over 90 (9)\n  90 or above (10)\n  over 1000 (0)\n",
+    assertEquals("dim=dim path=[] value=100 childCount=2\n  b (75)\n  a (25)\n", dsr.facets.getTopChildren(10, "dim").toString());
+    assertEquals("dim=field path=[] value=100 childCount=5\n  less than 10 (10)\n  less than or equal to 10 (11)\n  over 90 (9)\n  90 or above (10)\n  over 1000 (0)\n",
                  dsr.facets.getTopChildren(10, "field").toString());
 
     // Second search, drill down on dim=b:
@@ -171,8 +171,8 @@ public class TestRangeFacetCounts extend
     dsr = ds.search(null, ddq, 10);
 
     assertEquals(75, dsr.hits.totalHits);
-    assertEquals("value=100 childCount=2\n  b (75)\n  a (25)\n", dsr.facets.getTopChildren(10, "dim").toString());
-    assertEquals("value=75 childCount=5\n  less than 10 (7)\n  less than or equal to 10 (8)\n  over 90 (7)\n  90 or above (8)\n  over 1000 (0)\n",
+    assertEquals("dim=dim path=[] value=100 childCount=2\n  b (75)\n  a (25)\n", dsr.facets.getTopChildren(10, "dim").toString());
+    assertEquals("dim=field path=[] value=75 childCount=5\n  less than 10 (7)\n  less than or equal to 10 (8)\n  over 90 (7)\n  90 or above (8)\n  over 1000 (0)\n",
                  dsr.facets.getTopChildren(10, "field").toString());
 
     // Third search, drill down on "less than or equal to 10":
@@ -181,8 +181,8 @@ public class TestRangeFacetCounts extend
     dsr = ds.search(null, ddq, 10);
 
     assertEquals(11, dsr.hits.totalHits);
-    assertEquals("value=11 childCount=2\n  b (8)\n  a (3)\n", dsr.facets.getTopChildren(10, "dim").toString());
-    assertEquals("value=100 childCount=5\n  less than 10 (10)\n  less than or equal to 10 (11)\n  over 90 (9)\n  90 or above (10)\n  over 1000 (0)\n",
+    assertEquals("dim=dim path=[] value=11 childCount=2\n  b (8)\n  a (3)\n", dsr.facets.getTopChildren(10, "dim").toString());
+    assertEquals("dim=field path=[] value=100 childCount=5\n  less than 10 (10)\n  less than or equal to 10 (11)\n  over 90 (9)\n  90 or above (10)\n  over 1000 (0)\n",
                  dsr.facets.getTopChildren(10, "field").toString());
     IOUtils.close(tw, tr, td, w, r, d);
   }
@@ -211,7 +211,7 @@ public class TestRangeFacetCounts extend
         new DoubleRange("90 or above", 90.0, true, 100.0, false),
         new DoubleRange("over 1000", 1000.0, false, Double.POSITIVE_INFINITY, false));
                                          
-    assertEquals("value=100 childCount=5\n  less than 10 (10)\n  less than or equal to 10 (11)\n  over 90 (9)\n  90 or above (10)\n  over 1000 (0)\n",
+    assertEquals("dim=field path=[] value=100 childCount=5\n  less than 10 (10)\n  less than or equal to 10 (11)\n  over 90 (9)\n  90 or above (10)\n  over 1000 (0)\n",
                  facets.getTopChildren(10, "field").toString());
 
     IOUtils.close(w, r, d);
@@ -242,7 +242,7 @@ public class TestRangeFacetCounts extend
         new DoubleRange("90 or above", 90.0f, true, 100.0f, false),
         new DoubleRange("over 1000", 1000.0f, false, Double.POSITIVE_INFINITY, false));
     
-    assertEquals("value=100 childCount=5\n  less than 10 (10)\n  less than or equal to 10 (11)\n  over 90 (9)\n  90 or above (10)\n  over 1000 (0)\n",
+    assertEquals("dim=field path=[] value=100 childCount=5\n  less than 10 (10)\n  less than or equal to 10 (11)\n  over 90 (9)\n  90 or above (10)\n  over 1000 (0)\n",
                  facets.getTopChildren(10, "field").toString());
     
     IOUtils.close(w, r, d);
@@ -531,7 +531,7 @@ public class TestRangeFacetCounts extend
         new LongRange("90 or above", 90L, true, 100L, false),
         new LongRange("over 1000", 1000L, false, Long.MAX_VALUE, false));
     
-    assertEquals("value=100 childCount=5\n  less than 10 (8)\n  less than or equal to 10 (8)\n  over 90 (8)\n  90 or above (8)\n  over 1000 (0)\n",
+    assertEquals("dim=field path=[] value=100 childCount=5\n  less than 10 (8)\n  less than or equal to 10 (8)\n  over 90 (8)\n  90 or above (8)\n  over 1000 (0)\n",
                  facets.getTopChildren(10, "field").toString());
 
     IOUtils.close(w, r, d);
@@ -592,7 +592,11 @@ public class TestRangeFacetCounts extend
         new DoubleRange("< 20", 0.0, true, 20.0, false),
         new DoubleRange("< 50", 0.0, true, 50.0, false));
 
-    assertEquals("value=3 childCount=6\n  < 1 (0)\n  < 2 (1)\n  < 5 (3)\n  < 10 (3)\n  < 20 (3)\n  < 50 (3)\n", facets.getTopChildren(10, "field").toString());
+    assertEquals("dim=field path=[] value=3 childCount=6\n  < 1 (0)\n  < 2 (1)\n  < 5 (3)\n  < 10 (3)\n  < 20 (3)\n  < 50 (3)\n", facets.getTopChildren(10, "field").toString());
+
+    // Test drill-down:
+    assertEquals(1, s.search(new ConstantScoreQuery(new DoubleRange("< 2", 0.0, true, 2.0, false).getFilter(vs)), 10).totalHits);
+
     IOUtils.close(r, writer, dir);
   }
 }

Modified: lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestSortedSetDocValuesFacets.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestSortedSetDocValuesFacets.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestSortedSetDocValuesFacets.java (original)
+++ lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestSortedSetDocValuesFacets.java Mon Dec  2 23:44:13 2013
@@ -17,18 +17,24 @@ package org.apache.lucene.facet;
  * limitations under the License.
  */
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.lucene.document.Document;
-import org.apache.lucene.facet.FacetTestCase;
+import org.apache.lucene.document.Field;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.RandomIndexWriter;
 import org.apache.lucene.index.SlowCompositeReaderWrapper;
+import org.apache.lucene.index.Term;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.MatchAllDocsQuery;
+import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.search.TopDocs;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.IOUtils;
+import org.apache.lucene.util._TestUtil;
 
 public class TestSortedSetDocValuesFacets extends FacetTestCase {
 
@@ -69,8 +75,8 @@ public class TestSortedSetDocValuesFacet
 
     SortedSetDocValuesFacetCounts facets = new SortedSetDocValuesFacetCounts(state, c);
 
-    assertEquals("value=4 childCount=3\n  foo (2)\n  bar (1)\n  zoo (1)\n", facets.getTopChildren(10, "a").toString());
-    assertEquals("value=1 childCount=1\n  baz (1)\n", facets.getTopChildren(10, "b").toString());
+    assertEquals("dim=a path=[] value=4 childCount=3\n  foo (2)\n  bar (1)\n  zoo (1)\n", facets.getTopChildren(10, "a").toString());
+    assertEquals("dim=b path=[] value=1 childCount=1\n  baz (1)\n", facets.getTopChildren(10, "b").toString());
 
     // DrillDown:
     DrillDownQuery q = new DrillDownQuery(config);
@@ -172,9 +178,9 @@ public class TestSortedSetDocValuesFacet
     List<FacetResult> results = facets.getAllDims(10);
 
     assertEquals(3, results.size());
-    assertEquals("value=3 childCount=3\n  foo1 (1)\n  foo2 (1)\n  foo3 (1)\n", results.get(0).toString());
-    assertEquals("value=2 childCount=2\n  bar1 (1)\n  bar2 (1)\n", results.get(1).toString());
-    assertEquals("value=1 childCount=1\n  baz1 (1)\n", results.get(2).toString());
+    assertEquals("dim=a path=[] value=3 childCount=3\n  foo1 (1)\n  foo2 (1)\n  foo3 (1)\n", results.get(0).toString());
+    assertEquals("dim=b path=[] value=2 childCount=2\n  bar1 (1)\n  bar2 (1)\n", results.get(1).toString());
+    assertEquals("dim=c path=[] value=1 childCount=1\n  baz1 (1)\n", results.get(2).toString());
 
     searcher.getIndexReader().close();
     dir.close();
@@ -214,18 +220,12 @@ public class TestSortedSetDocValuesFacet
     SortedSetDocValuesFacetCounts facets = new SortedSetDocValuesFacetCounts(state, c);
 
     // Ask for top 10 labels for any dims that have counts:
-    assertEquals("value=2 childCount=2\n  foo1 (1)\n  foo2 (1)\n", facets.getTopChildren(10, "a").toString());
+    assertEquals("dim=a path=[] value=2 childCount=2\n  foo1 (1)\n  foo2 (1)\n", facets.getTopChildren(10, "a").toString());
 
     searcher.getIndexReader().close();
     dir.close();
   }
 
-  // nocommit test different delim char & using the default
-  // one in a dim
-
-  // nocommit in the sparse case test that we are really
-  // sorting by the correct dim count
-
   public void testSlowCompositeReaderWrapper() throws Exception {
     assumeTrue("Test requires SortedSetDV support", defaultCodecSupportsSortedSet());
     Directory dir = newDirectory();
@@ -255,8 +255,96 @@ public class TestSortedSetDocValuesFacet
     Facets facets = new SortedSetDocValuesFacetCounts(state, c);
 
     // Ask for top 10 labels for any dims that have counts:
-    assertEquals("value=2 childCount=2\n  foo1 (1)\n  foo2 (1)\n", facets.getTopChildren(10, "a").toString());
+    assertEquals("dim=a path=[] value=2 childCount=2\n  foo1 (1)\n  foo2 (1)\n", facets.getTopChildren(10, "a").toString());
 
     IOUtils.close(writer, searcher.getIndexReader(), dir);
   }
+
+
+  public void testRandom() throws Exception {
+    assumeTrue("Test requires SortedSetDV support", defaultCodecSupportsSortedSet());
+    String[] tokens = getRandomTokens(10);
+    Directory indexDir = newDirectory();
+    Directory taxoDir = newDirectory();
+
+    RandomIndexWriter w = new RandomIndexWriter(random(), indexDir);
+    FacetsConfig config = new FacetsConfig();
+    int numDocs = atLeast(1000);
+    int numDims = _TestUtil.nextInt(random(), 1, 7);
+    List<TestDoc> testDocs = getRandomDocs(tokens, numDocs, numDims);
+    for(TestDoc testDoc : testDocs) {
+      Document doc = new Document();
+      doc.add(newStringField("content", testDoc.content, Field.Store.NO));
+      for(int j=0;j<numDims;j++) {
+        if (testDoc.dims[j] != null) {
+          doc.add(new SortedSetDocValuesFacetField("dim" + j, testDoc.dims[j]));
+        }
+      }
+      w.addDocument(config.build(doc));
+    }
+
+    // NRT open
+    IndexSearcher searcher = newSearcher(w.getReader());
+    
+    // Per-top-reader state:
+    SortedSetDocValuesReaderState state = new SortedSetDocValuesReaderState(searcher.getIndexReader());
+
+    int iters = atLeast(100);
+    for(int iter=0;iter<iters;iter++) {
+      String searchToken = tokens[random().nextInt(tokens.length)];
+      if (VERBOSE) {
+        System.out.println("\nTEST: iter content=" + searchToken);
+      }
+      FacetsCollector fc = new FacetsCollector();
+      TopDocs hits = FacetsCollector.search(searcher, new TermQuery(new Term("content", searchToken)), 10, fc);
+      Facets facets = new SortedSetDocValuesFacetCounts(state, fc);
+
+      // Slow, yet hopefully bug-free, faceting:
+      @SuppressWarnings({"rawtypes","unchecked"}) Map<String,Integer>[] expectedCounts = new HashMap[numDims];
+      for(int i=0;i<numDims;i++) {
+        expectedCounts[i] = new HashMap<String,Integer>();
+      }
+
+      for(TestDoc doc : testDocs) {
+        if (doc.content.equals(searchToken)) {
+          for(int j=0;j<numDims;j++) {
+            if (doc.dims[j] != null) {
+              Integer v = expectedCounts[j].get(doc.dims[j]);
+              if (v == null) {
+                expectedCounts[j].put(doc.dims[j], 1);
+              } else {
+                expectedCounts[j].put(doc.dims[j], v.intValue() + 1);
+              }
+            }
+          }
+        }
+      }
+
+      List<FacetResult> expected = new ArrayList<FacetResult>();
+      for(int i=0;i<numDims;i++) {
+        List<LabelAndValue> labelValues = new ArrayList<LabelAndValue>();
+        int totCount = 0;
+        for(Map.Entry<String,Integer> ent : expectedCounts[i].entrySet()) {
+          labelValues.add(new LabelAndValue(ent.getKey(), ent.getValue()));
+          totCount += ent.getValue();
+        }
+        sortLabelValues(labelValues);
+        if (totCount > 0) {
+          expected.add(new FacetResult("dim" + i, new String[0], totCount, labelValues.toArray(new LabelAndValue[labelValues.size()]), labelValues.size()));
+        }
+      }
+
+      // Sort by highest value, tie break by value:
+      sortFacetResults(expected);
+
+      List<FacetResult> actual = facets.getAllDims(10);
+
+      // Messy: fixup ties
+      //sortTies(actual);
+
+      assertEquals(expected, actual);
+    }
+
+    IOUtils.close(w, searcher.getIndexReader(), indexDir, taxoDir);
+  }
 }

Modified: lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestTaxonomyFacetAssociations.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestTaxonomyFacetAssociations.java?rev=1547241&r1=1547240&r2=1547241&view=diff
==============================================================================
--- lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestTaxonomyFacetAssociations.java (original)
+++ lucene/dev/branches/lucene5339/lucene/facet/src/test/org/apache/lucene/facet/TestTaxonomyFacetAssociations.java Mon Dec  2 23:44:13 2013
@@ -101,7 +101,7 @@ public class TestTaxonomyFacetAssociatio
     searcher.search(new MatchAllDocsQuery(), fc);
 
     Facets facets = new TaxonomyFacetSumIntAssociations("$facets.int", taxoReader, config, fc);
-    assertEquals("value=-1 childCount=2\n  a (200)\n  b (150)\n", facets.getTopChildren(10, "int").toString());
+    assertEquals("dim=int path=[] value=-1 childCount=2\n  a (200)\n  b (150)\n", facets.getTopChildren(10, "int").toString());
     assertEquals("Wrong count for category 'a'!", 200, facets.getSpecificValue("int", "a").intValue());
     assertEquals("Wrong count for category 'b'!", 150, facets.getSpecificValue("int", "b").intValue());
   }
@@ -113,7 +113,7 @@ public class TestTaxonomyFacetAssociatio
     searcher.search(new MatchAllDocsQuery(), fc);
     
     Facets facets = new TaxonomyFacetSumFloatAssociations("$facets.float", taxoReader, config, fc);
-    assertEquals("value=-1.0 childCount=2\n  a (50.0)\n  b (9.999995)\n", facets.getTopChildren(10, "float").toString());
+    assertEquals("dim=float path=[] value=-1.0 childCount=2\n  a (50.0)\n  b (9.999995)\n", facets.getTopChildren(10, "float").toString());
     assertEquals("Wrong count for category 'a'!", 50f, facets.getSpecificValue("float", "a").floatValue(), 0.00001);
     assertEquals("Wrong count for category 'b'!", 10f, facets.getSpecificValue("float", "b").floatValue(), 0.00001);
   }