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/08/21 00:38:28 UTC

svn commit: r1515999 - in /lucene/dev/trunk/lucene/facet/src: java/org/apache/lucene/facet/range/RangeAccumulator.java test/org/apache/lucene/facet/range/TestRangeAccumulator.java

Author: mikemccand
Date: Tue Aug 20 22:38:28 2013
New Revision: 1515999

URL: http://svn.apache.org/r1515999
Log:
LUCENE-5178: handle missing values in range facets

Modified:
    lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/range/RangeAccumulator.java
    lucene/dev/trunk/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeAccumulator.java

Modified: lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/range/RangeAccumulator.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/range/RangeAccumulator.java?rev=1515999&r1=1515998&r2=1515999&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/range/RangeAccumulator.java (original)
+++ lucene/dev/trunk/lucene/facet/src/java/org/apache/lucene/facet/range/RangeAccumulator.java Tue Aug 20 22:38:28 2013
@@ -30,6 +30,7 @@ import org.apache.lucene.facet.search.Fa
 import org.apache.lucene.facet.search.FacetsCollector.MatchingDocs;
 import org.apache.lucene.facet.taxonomy.CategoryPath;
 import org.apache.lucene.index.NumericDocValues;
+import org.apache.lucene.util.Bits;
 
 /** Uses a {@link NumericDocValues} and accumulates
  *  counts for provided ranges.  This is dynamic (does not
@@ -86,10 +87,19 @@ public class RangeAccumulator extends Fa
         if (ndv == null) {
           continue; // no numeric values for this field in this reader
         }
+        Bits docsWithField = hits.context.reader().getDocsWithField(ranges.field);
+
         final int length = hits.bits.length();
         int doc = 0;
         while (doc < length && (doc = hits.bits.nextSetBit(doc)) != -1) {
           long v = ndv.get(doc);
+
+          // Skip missing docs:
+          if (v == 0 && docsWithField.get(doc) == false) {
+            doc++;
+            continue;
+          }
+
           // TODO: if all ranges are non-overlapping, we
           // should instead do a bin-search up front
           // (really, a specialized case of the interval

Modified: lucene/dev/trunk/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeAccumulator.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeAccumulator.java?rev=1515999&r1=1515998&r2=1515999&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeAccumulator.java (original)
+++ lucene/dev/trunk/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeAccumulator.java Tue Aug 20 22:38:28 2013
@@ -632,5 +632,43 @@ public class TestRangeAccumulator extend
     r.close();
     dir.close();
   }
-}
 
+  // LUCENE-5178
+  public void testMissingValues() throws Exception {
+    Directory d = newDirectory();
+    RandomIndexWriter w = new RandomIndexWriter(random(), d);
+    Document doc = new Document();
+    NumericDocValuesField field = new NumericDocValuesField("field", 0L);
+    doc.add(field);
+    for(long l=0;l<100;l++) {
+      if (l % 5 == 0) {
+        // Every 5th doc is missing the value:
+        w.addDocument(new Document());
+        continue;
+      }
+      field.setLongValue(l);
+      w.addDocument(doc);
+    }
+
+    IndexReader r = w.getReader();
+    w.close();
+
+    RangeAccumulator a = new RangeAccumulator(new RangeFacetRequest<LongRange>("field",
+        new LongRange("less than 10", 0L, true, 10L, false),
+        new LongRange("less than or equal to 10", 0L, true, 10L, true),
+        new LongRange("over 90", 90L, false, 100L, false),
+        new LongRange("90 or above", 90L, true, 100L, false),
+        new LongRange("over 1000", 1000L, false, Long.MAX_VALUE, false)));
+    
+    FacetsCollector fc = FacetsCollector.create(a);
+
+    IndexSearcher s = newSearcher(r);
+    s.search(new MatchAllDocsQuery(), fc);
+    List<FacetResult> result = fc.getFacetResults();
+    assertEquals(1, result.size());
+    assertEquals("field (0)\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", FacetTestUtils.toSimpleString(result.get(0)));
+    
+    r.close();
+    d.close();
+  }
+}