LUCENE-5178: handle missing values in range facets

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1515999 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2013-08-20 22:38:28 +00:00
parent 7e2be6a4a8
commit 4a010bce9b
2 changed files with 49 additions and 1 deletions

View File

@ -30,6 +30,7 @@ import org.apache.lucene.facet.search.FacetsAccumulator;
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 FacetsAccumulator {
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

View File

@ -632,5 +632,43 @@ public class TestRangeAccumulator extends FacetTestCase {
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();
}
}