LUCENE-10614: Properly support getTopChildren in RangeFacetCounts (#974)

This commit is contained in:
Yuting Gan 2022-07-11 09:04:46 -07:00 committed by GitHub
parent 128869d63a
commit 5ef7e5025d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 170 additions and 24 deletions

View File

@ -109,6 +109,8 @@ Improvements
* GITHUB#983: AbstractSortedSetDocValueFacetCounts internal code cleanup/refactoring. (Greg Miller) * GITHUB#983: AbstractSortedSetDocValueFacetCounts internal code cleanup/refactoring. (Greg Miller)
* LUCENE-10614: Properly support getTopChildren in RangeFacetCounts. (Yuting Gan)
Optimizations Optimizations
--------------------- ---------------------
* LUCENE-8519: MultiDocValues.getNormValues should not call getMergedFieldInfos (Rushabh Shah) * LUCENE-8519: MultiDocValues.getNormValues should not call getMergedFieldInfos (Rushabh Shah)

View File

@ -227,7 +227,7 @@ public class DistanceFacetsExample implements Closeable {
FIVE_KM, FIVE_KM,
TEN_KM); TEN_KM);
return facets.getTopChildren(10, "field"); return facets.getAllChildren("field");
} }
/** User drills down on the specified range. */ /** User drills down on the specified range. */

View File

@ -94,7 +94,7 @@ public class RangeFacetsExample implements Closeable {
FacetsCollector.search(searcher, new MatchAllDocsQuery(), 10, fc); FacetsCollector.search(searcher, new MatchAllDocsQuery(), 10, fc);
Facets facets = new LongRangeFacetCounts("timestamp", fc, PAST_HOUR, PAST_SIX_HOURS, PAST_DAY); Facets facets = new LongRangeFacetCounts("timestamp", fc, PAST_HOUR, PAST_SIX_HOURS, PAST_DAY);
return facets.getTopChildren(10, "timestamp"); return facets.getAllChildren("timestamp");
} }
/** User drills down on the specified range. */ /** User drills down on the specified range. */

View File

@ -36,6 +36,7 @@ import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreMode; import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer; import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight; import org.apache.lucene.search.Weight;
import org.apache.lucene.util.PriorityQueue;
/** /**
* Base class for range faceting. * Base class for range faceting.
@ -232,20 +233,43 @@ abstract class RangeFacetCounts extends Facets {
return new FacetResult(dim, path, totCount, labelValues, labelValues.length); return new FacetResult(dim, path, totCount, labelValues, labelValues.length);
} }
// The current getTopChildren method is not returning "top" ranges. Instead, it returns all
// user-provided ranges in
// the order the user specified them when instantiating. This concept is being introduced and
// supported in the
// getAllChildren functionality in LUCENE-10550. getTopChildren is temporarily calling
// getAllChildren to maintain its
// current behavior, and the current implementation will be replaced by an actual "top children"
// implementation
// in LUCENE-10614
// TODO: fix getTopChildren in LUCENE-10614
@Override @Override
public FacetResult getTopChildren(int topN, String dim, String... path) throws IOException { public FacetResult getTopChildren(int topN, String dim, String... path) throws IOException {
validateTopN(topN); validateTopN(topN);
return getAllChildren(dim, path); validateDimAndPathForGetChildren(dim, path);
PriorityQueue<Entry> pq =
new PriorityQueue<>(Math.min(topN, counts.length)) {
@Override
protected boolean lessThan(Entry a, Entry b) {
int cmp = Integer.compare(a.count, b.count);
if (cmp == 0) {
cmp = b.label.compareTo(a.label);
}
return cmp < 0;
}
};
int childCount = 0;
Entry e = null;
for (int i = 0; i < counts.length; i++) {
if (counts[i] != 0) {
childCount++;
if (e == null) {
e = new Entry();
}
e.label = ranges[i].label;
e.count = counts[i];
e = pq.insertWithOverflow(e);
}
}
LabelAndValue[] results = new LabelAndValue[pq.size()];
while (pq.size() != 0) {
Entry entry = pq.pop();
results[pq.size()] = new LabelAndValue(entry.label, entry.count);
}
return new FacetResult(dim, path, totCount, results, childCount);
} }
@Override @Override
@ -285,4 +309,10 @@ abstract class RangeFacetCounts extends Facets {
throw new IllegalArgumentException("path.length should be 0"); throw new IllegalArgumentException("path.length should be 0");
} }
} }
/** Reusable entry to hold range label and int count. */
private static final class Entry {
int count;
String label;
}
} }

View File

@ -18,6 +18,7 @@ package org.apache.lucene.facet.range;
import com.carrotsearch.randomizedtesting.generators.RandomNumbers; import com.carrotsearch.randomizedtesting.generators.RandomNumbers;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -104,6 +105,11 @@ public class TestRangeFacetCounts extends FacetTestCase {
"dim=field path=[] value=22 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", "dim=field path=[] value=22 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()); result.toString());
result = facets.getTopChildren(4, "field");
assertEquals(
"dim=field path=[] value=22 childCount=5\n less than or equal to 10 (11)\n 90 or above (10)\n less than 10 (10)\n over 90 (9)\n",
result.toString());
// test getTopChildren(0, dim) // test getTopChildren(0, dim)
expectThrows( expectThrows(
IllegalArgumentException.class, IllegalArgumentException.class,
@ -156,6 +162,18 @@ public class TestRangeFacetCounts extends FacetTestCase {
"dim=field path=[] value=22 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", "dim=field path=[] value=22 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()); result.toString());
result = facets.getTopChildren(4, "field");
assertEquals(
"dim=field path=[] value=22 childCount=5\n less than or equal to 10 (11)\n 90 or above (10)\n less than 10 (10)\n over 90 (9)\n",
result.toString());
// test getTopChildren(0, dim)
expectThrows(
IllegalArgumentException.class,
() -> {
facets.getTopChildren(0, "field");
});
r.close(); r.close();
d.close(); d.close();
} }
@ -206,6 +224,11 @@ public class TestRangeFacetCounts extends FacetTestCase {
"dim=field path=[] value=21 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", "dim=field path=[] value=21 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",
result.toString()); result.toString());
result = facets.getTopChildren(4, "field");
assertEquals(
"dim=field path=[] value=21 childCount=4\n less than or equal to 10 (11)\n 90 or above (10)\n less than 10 (10)\n over 90 (9)\n",
result.toString());
r.close(); r.close();
d.close(); d.close();
} }
@ -244,23 +267,23 @@ public class TestRangeFacetCounts extends FacetTestCase {
List<FacetResult> result = facets.getAllDims(10); List<FacetResult> result = facets.getAllDims(10);
assertEquals(1, result.size()); assertEquals(1, result.size());
assertEquals( assertEquals(
"dim=field path=[] value=22 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", "dim=field path=[] value=22 childCount=5\n less than or equal to 10 (11)\n 90 or above (10)\n less than 10 (10)\n over 90 (9)\n over 1000 (1)\n",
result.get(0).toString()); result.get(0).toString());
// test getAllDims(1) // test getAllDims(1)
List<FacetResult> test1Child = facets.getAllDims(1); result = facets.getAllDims(1);
assertEquals(1, test1Child.size()); assertEquals(1, result.size());
assertEquals( assertEquals(
"dim=field path=[] value=22 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", "dim=field path=[] value=22 childCount=5\n less than or equal to 10 (11)\n",
test1Child.get(0).toString()); result.get(0).toString());
// test default implementation of getTopDims // test default implementation of getTopDims
List<FacetResult> topNDimsResult = facets.getTopDims(1, 1); List<FacetResult> topNDimsResult = facets.getTopDims(1, 1);
assertEquals(test1Child, topNDimsResult); assertEquals(result, topNDimsResult);
// test getTopDims(0, 1) // test getTopDims(0, 1)
List<FacetResult> topDimsResults2 = facets.getTopDims(0, 1); topNDimsResult = facets.getTopDims(0, 1);
assertEquals(0, topDimsResults2.size()); assertEquals(0, topNDimsResult.size());
// test getAllDims(0) // test getAllDims(0)
expectThrows( expectThrows(
@ -332,6 +355,11 @@ public class TestRangeFacetCounts extends FacetTestCase {
"dim=field path=[] value=3 childCount=6\n min (1)\n max (1)\n all0 (3)\n all1 (2)\n all2 (2)\n all3 (1)\n", "dim=field path=[] value=3 childCount=6\n min (1)\n max (1)\n all0 (3)\n all1 (2)\n all2 (2)\n all3 (1)\n",
result.toString()); result.toString());
result = facets.getTopChildren(5, "field");
assertEquals(
"dim=field path=[] value=3 childCount=6\n all0 (3)\n all1 (2)\n all2 (2)\n all3 (1)\n max (1)\n",
result.toString());
r.close(); r.close();
d.close(); d.close();
} }
@ -368,6 +396,11 @@ public class TestRangeFacetCounts extends FacetTestCase {
assertEquals( assertEquals(
"dim=field path=[] value=41 childCount=4\n 0-10 (11)\n 10-20 (11)\n 20-30 (11)\n 30-40 (11)\n", "dim=field path=[] value=41 childCount=4\n 0-10 (11)\n 10-20 (11)\n 20-30 (11)\n 30-40 (11)\n",
result.toString()); result.toString());
result = facets.getTopChildren(3, "field");
assertEquals(
"dim=field path=[] value=41 childCount=4\n 0-10 (11)\n 10-20 (11)\n 20-30 (11)\n",
result.toString());
r.close(); r.close();
d.close(); d.close();
} }
@ -393,6 +426,8 @@ public class TestRangeFacetCounts extends FacetTestCase {
FacetResult result = facets.getAllChildren("field"); FacetResult result = facets.getAllChildren("field");
assertEquals("dim=field path=[] value=0 childCount=0\n", result.toString()); assertEquals("dim=field path=[] value=0 childCount=0\n", result.toString());
result = facets.getTopChildren(1, "field");
assertEquals("dim=field path=[] value=0 childCount=0\n", result.toString());
r.close(); r.close();
d.close(); d.close();
@ -422,6 +457,8 @@ public class TestRangeFacetCounts extends FacetTestCase {
FacetResult result = facets.getAllChildren("field"); FacetResult result = facets.getAllChildren("field");
assertEquals("dim=field path=[] value=0 childCount=0\n", result.toString()); assertEquals("dim=field path=[] value=0 childCount=0\n", result.toString());
result = facets.getTopChildren(1, "field");
assertEquals("dim=field path=[] value=0 childCount=0\n", result.toString());
r.close(); r.close();
d.close(); d.close();
@ -518,7 +555,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
"dim=dim path=[] value=100 childCount=2\n b (75)\n a (25)\n", "dim=dim path=[] value=100 childCount=2\n b (75)\n a (25)\n",
dsr.facets.getTopChildren(10, "dim").toString()); dsr.facets.getTopChildren(10, "dim").toString());
assertEquals( assertEquals(
"dim=field path=[] value=21 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", "dim=field path=[] value=21 childCount=4\n less than or equal to 10 (11)\n 90 or above (10)\n less than 10 (10)\n over 90 (9)\n",
dsr.facets.getTopChildren(10, "field").toString()); dsr.facets.getTopChildren(10, "field").toString());
// Second search, drill down on dim=b: // Second search, drill down on dim=b:
@ -531,7 +568,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
"dim=dim path=[] value=100 childCount=2\n b (75)\n a (25)\n", "dim=dim path=[] value=100 childCount=2\n b (75)\n a (25)\n",
dsr.facets.getTopChildren(10, "dim").toString()); dsr.facets.getTopChildren(10, "dim").toString());
assertEquals( assertEquals(
"dim=field path=[] value=16 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", "dim=field path=[] value=16 childCount=4\n 90 or above (8)\n less than or equal to 10 (8)\n less than 10 (7)\n over 90 (7)\n",
dsr.facets.getTopChildren(10, "field").toString()); dsr.facets.getTopChildren(10, "field").toString());
// Third search, drill down on "less than or equal to 10": // Third search, drill down on "less than or equal to 10":
@ -544,7 +581,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
"dim=dim path=[] value=11 childCount=2\n b (8)\n a (3)\n", "dim=dim path=[] value=11 childCount=2\n b (8)\n a (3)\n",
dsr.facets.getTopChildren(10, "dim").toString()); dsr.facets.getTopChildren(10, "dim").toString());
assertEquals( assertEquals(
"dim=field path=[] value=21 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", "dim=field path=[] value=21 childCount=4\n less than or equal to 10 (11)\n 90 or above (10)\n less than 10 (10)\n over 90 (9)\n",
dsr.facets.getTopChildren(10, "field").toString()); dsr.facets.getTopChildren(10, "field").toString());
w.close(); w.close();
IOUtils.close(tw, tr, td, r, d); IOUtils.close(tw, tr, td, r, d);
@ -578,6 +615,9 @@ public class TestRangeFacetCounts extends FacetTestCase {
assertEquals( assertEquals(
"dim=field path=[] value=21 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", "dim=field path=[] value=21 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.getAllChildren("field").toString()); facets.getAllChildren("field").toString());
assertEquals(
"dim=field path=[] value=21 childCount=4\n less than or equal to 10 (11)\n 90 or above (10)\n less than 10 (10)\n over 90 (9)\n",
facets.getTopChildren(4, "field").toString());
w.close(); w.close();
IOUtils.close(r, d); IOUtils.close(r, d);
} }
@ -611,9 +651,14 @@ public class TestRangeFacetCounts extends FacetTestCase {
new DoubleRange("90 or above", 90.0, true, 100.0, false), new DoubleRange("90 or above", 90.0, true, 100.0, false),
new DoubleRange("over 1000", 1000.0, false, Double.POSITIVE_INFINITY, false)); new DoubleRange("over 1000", 1000.0, false, Double.POSITIVE_INFINITY, false));
facets.getTopChildren(4, "field");
assertEquals( assertEquals(
"dim=field path=[] value=21 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", "dim=field path=[] value=21 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.getAllChildren("field").toString()); facets.getAllChildren("field").toString());
assertEquals(
"dim=field path=[] value=21 childCount=4\n less than or equal to 10 (11)\n 90 or above (10)\n less than 10 (10)\n over 90 (9)\n",
facets.getTopChildren(4, "field").toString());
facets.getTopChildren(4, "field");
w.close(); w.close();
IOUtils.close(r, d); IOUtils.close(r, d);
} }
@ -663,6 +708,10 @@ public class TestRangeFacetCounts extends FacetTestCase {
assertEquals( assertEquals(
"dim=field path=[] value=21 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", "dim=field path=[] value=21 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",
result.toString()); result.toString());
result = facets.getTopChildren(4, "field");
assertEquals(
"dim=field path=[] value=21 childCount=4\n less than or equal to 10 (11)\n 90 or above (10)\n less than 10 (10)\n over 90 (9)\n",
result.toString());
r.close(); r.close();
d.close(); d.close();
@ -702,6 +751,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
int numRange = TestUtil.nextInt(random(), 1, 100); int numRange = TestUtil.nextInt(random(), 1, 100);
LongRange[] ranges = new LongRange[numRange]; LongRange[] ranges = new LongRange[numRange];
int[] expectedCounts = new int[numRange]; int[] expectedCounts = new int[numRange];
int[] expectedTopNChildrenCounts = new int[numRange];
long minAcceptedValue = Long.MAX_VALUE; long minAcceptedValue = Long.MAX_VALUE;
long maxAcceptedValue = Long.MIN_VALUE; long maxAcceptedValue = Long.MIN_VALUE;
for (int rangeID = 0; rangeID < numRange; rangeID++) { for (int rangeID = 0; rangeID < numRange; rangeID++) {
@ -769,6 +819,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
} }
if (accept) { if (accept) {
expectedCounts[rangeID]++; expectedCounts[rangeID]++;
expectedTopNChildrenCounts[rangeID]++;
minAcceptedValue = Math.min(minAcceptedValue, values[i]); minAcceptedValue = Math.min(minAcceptedValue, values[i]);
maxAcceptedValue = Math.max(maxAcceptedValue, values[i]); maxAcceptedValue = Math.max(maxAcceptedValue, values[i]);
} }
@ -802,6 +853,9 @@ public class TestRangeFacetCounts extends FacetTestCase {
} }
FacetResult result = facets.getAllChildren("field"); FacetResult result = facets.getAllChildren("field");
assertEquals(numRange, result.labelValues.length); assertEquals(numRange, result.labelValues.length);
FacetResult topNResult = facets.getTopChildren(numRange, "field");
Arrays.sort(expectedTopNChildrenCounts);
for (int rangeID = 0; rangeID < numRange; rangeID++) { for (int rangeID = 0; rangeID < numRange; rangeID++) {
if (VERBOSE) { if (VERBOSE) {
System.out.println(" range " + rangeID + " expectedCount=" + expectedCounts[rangeID]); System.out.println(" range " + rangeID + " expectedCount=" + expectedCounts[rangeID]);
@ -809,6 +863,12 @@ public class TestRangeFacetCounts extends FacetTestCase {
LabelAndValue subNode = result.labelValues[rangeID]; LabelAndValue subNode = result.labelValues[rangeID];
assertEquals("r" + rangeID, subNode.label); assertEquals("r" + rangeID, subNode.label);
assertEquals(expectedCounts[rangeID], subNode.value.intValue()); assertEquals(expectedCounts[rangeID], subNode.value.intValue());
// test topNChildren and assert topNResults are sorted by count
if (rangeID < topNResult.labelValues.length) {
LabelAndValue topNsubNode = topNResult.labelValues[rangeID];
assertEquals(
expectedTopNChildrenCounts[numRange - rangeID - 1], topNsubNode.value.intValue());
}
LongRange range = ranges[rangeID]; LongRange range = ranges[rangeID];
@ -828,6 +888,9 @@ public class TestRangeFacetCounts extends FacetTestCase {
Facets facets = new LongRangeFacetCounts("field", vs, sfc, fastMatchQuery, ranges); Facets facets = new LongRangeFacetCounts("field", vs, sfc, fastMatchQuery, ranges);
FacetResult result = facets.getAllChildren("field"); FacetResult result = facets.getAllChildren("field");
assertEquals(numRange, result.labelValues.length); assertEquals(numRange, result.labelValues.length);
FacetResult topNResult = facets.getTopChildren(numRange, "field");
Arrays.sort(expectedTopNChildrenCounts);
for (int rangeID = 0; rangeID < numRange; rangeID++) { for (int rangeID = 0; rangeID < numRange; rangeID++) {
if (VERBOSE) { if (VERBOSE) {
System.out.println(" range " + rangeID + " expectedCount=" + expectedCounts[rangeID]); System.out.println(" range " + rangeID + " expectedCount=" + expectedCounts[rangeID]);
@ -836,6 +899,13 @@ public class TestRangeFacetCounts extends FacetTestCase {
assertEquals("r" + rangeID, subNode.label); assertEquals("r" + rangeID, subNode.label);
assertEquals(expectedCounts[rangeID], subNode.value.intValue()); assertEquals(expectedCounts[rangeID], subNode.value.intValue());
// test topNChildren and assert topNResults are sorted by count
if (rangeID < topNResult.labelValues.length) {
LabelAndValue topNsubNode = topNResult.labelValues[rangeID];
assertEquals(
expectedTopNChildrenCounts[numRange - rangeID - 1], topNsubNode.value.intValue());
}
LongRange range = ranges[rangeID]; LongRange range = ranges[rangeID];
// Test drill-down: // Test drill-down:
@ -895,6 +965,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
int numRange = TestUtil.nextInt(random(), 1, 100); int numRange = TestUtil.nextInt(random(), 1, 100);
LongRange[] ranges = new LongRange[numRange]; LongRange[] ranges = new LongRange[numRange];
int[] expectedCounts = new int[numRange]; int[] expectedCounts = new int[numRange];
int[] expectedTopNChildrenCounts = new int[numRange];
long minAcceptedValue = Long.MAX_VALUE; long minAcceptedValue = Long.MAX_VALUE;
long maxAcceptedValue = Long.MIN_VALUE; long maxAcceptedValue = Long.MIN_VALUE;
for (int rangeID = 0; rangeID < numRange; rangeID++) { for (int rangeID = 0; rangeID < numRange; rangeID++) {
@ -963,6 +1034,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
} }
if (accept) { if (accept) {
expectedCounts[rangeID]++; expectedCounts[rangeID]++;
expectedTopNChildrenCounts[rangeID]++;
minAcceptedValue = Math.min(minAcceptedValue, values[i][j]); minAcceptedValue = Math.min(minAcceptedValue, values[i][j]);
maxAcceptedValue = Math.max(maxAcceptedValue, values[i][j]); maxAcceptedValue = Math.max(maxAcceptedValue, values[i][j]);
break; // ensure each doc can contribute at most 1 count to each range break; // ensure each doc can contribute at most 1 count to each range
@ -994,6 +1066,9 @@ public class TestRangeFacetCounts extends FacetTestCase {
} }
FacetResult result = facets.getAllChildren("field"); FacetResult result = facets.getAllChildren("field");
assertEquals(numRange, result.labelValues.length); assertEquals(numRange, result.labelValues.length);
FacetResult topNResult = facets.getTopChildren(numRange, "field");
Arrays.sort(expectedTopNChildrenCounts);
for (int rangeID = 0; rangeID < numRange; rangeID++) { for (int rangeID = 0; rangeID < numRange; rangeID++) {
if (VERBOSE) { if (VERBOSE) {
System.out.println(" range " + rangeID + " expectedCount=" + expectedCounts[rangeID]); System.out.println(" range " + rangeID + " expectedCount=" + expectedCounts[rangeID]);
@ -1001,6 +1076,12 @@ public class TestRangeFacetCounts extends FacetTestCase {
LabelAndValue subNode = result.labelValues[rangeID]; LabelAndValue subNode = result.labelValues[rangeID];
assertEquals("r" + rangeID, subNode.label); assertEquals("r" + rangeID, subNode.label);
assertEquals(expectedCounts[rangeID], subNode.value.intValue()); assertEquals(expectedCounts[rangeID], subNode.value.intValue());
// test topNChildren and assert topNResults are sorted by count
if (rangeID < topNResult.labelValues.length) {
LabelAndValue topNsubNode = topNResult.labelValues[rangeID];
assertEquals(
expectedTopNChildrenCounts[numRange - rangeID - 1], topNsubNode.value.intValue());
}
LongRange range = ranges[rangeID]; LongRange range = ranges[rangeID];
@ -1052,6 +1133,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
int numRange = TestUtil.nextInt(random(), 1, 5); int numRange = TestUtil.nextInt(random(), 1, 5);
DoubleRange[] ranges = new DoubleRange[numRange]; DoubleRange[] ranges = new DoubleRange[numRange];
int[] expectedCounts = new int[numRange]; int[] expectedCounts = new int[numRange];
int[] expectedTopNChildrenCounts = new int[numRange];
double minAcceptedValue = Double.POSITIVE_INFINITY; double minAcceptedValue = Double.POSITIVE_INFINITY;
double maxAcceptedValue = Double.NEGATIVE_INFINITY; double maxAcceptedValue = Double.NEGATIVE_INFINITY;
for (int rangeID = 0; rangeID < numRange; rangeID++) { for (int rangeID = 0; rangeID < numRange; rangeID++) {
@ -1117,6 +1199,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
} }
if (accept) { if (accept) {
expectedCounts[rangeID]++; expectedCounts[rangeID]++;
expectedTopNChildrenCounts[rangeID]++;
minAcceptedValue = Math.min(minAcceptedValue, values[i]); minAcceptedValue = Math.min(minAcceptedValue, values[i]);
maxAcceptedValue = Math.max(maxAcceptedValue, values[i]); maxAcceptedValue = Math.max(maxAcceptedValue, values[i]);
} }
@ -1152,6 +1235,9 @@ public class TestRangeFacetCounts extends FacetTestCase {
} }
FacetResult result = facets.getAllChildren("field"); FacetResult result = facets.getAllChildren("field");
assertEquals(numRange, result.labelValues.length); assertEquals(numRange, result.labelValues.length);
FacetResult topNResult = facets.getTopChildren(numRange, "field");
Arrays.sort(expectedTopNChildrenCounts);
for (int rangeID = 0; rangeID < numRange; rangeID++) { for (int rangeID = 0; rangeID < numRange; rangeID++) {
if (VERBOSE) { if (VERBOSE) {
System.out.println(" range " + rangeID + " expectedCount=" + expectedCounts[rangeID]); System.out.println(" range " + rangeID + " expectedCount=" + expectedCounts[rangeID]);
@ -1159,6 +1245,12 @@ public class TestRangeFacetCounts extends FacetTestCase {
LabelAndValue subNode = result.labelValues[rangeID]; LabelAndValue subNode = result.labelValues[rangeID];
assertEquals("r" + rangeID, subNode.label); assertEquals("r" + rangeID, subNode.label);
assertEquals(expectedCounts[rangeID], subNode.value.intValue()); assertEquals(expectedCounts[rangeID], subNode.value.intValue());
// test topNChildren and assert topNResults are sorted by count
if (rangeID < topNResult.labelValues.length) {
LabelAndValue topNsubNode = topNResult.labelValues[rangeID];
assertEquals(
expectedTopNChildrenCounts[numRange - rangeID - 1], topNsubNode.value.intValue());
}
DoubleRange range = ranges[rangeID]; DoubleRange range = ranges[rangeID];
@ -1218,6 +1310,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
int numRange = TestUtil.nextInt(random(), 1, 5); int numRange = TestUtil.nextInt(random(), 1, 5);
DoubleRange[] ranges = new DoubleRange[numRange]; DoubleRange[] ranges = new DoubleRange[numRange];
int[] expectedCounts = new int[numRange]; int[] expectedCounts = new int[numRange];
int[] expectedTopNChildrenCounts = new int[numRange];
double minAcceptedValue = Double.POSITIVE_INFINITY; double minAcceptedValue = Double.POSITIVE_INFINITY;
double maxAcceptedValue = Double.NEGATIVE_INFINITY; double maxAcceptedValue = Double.NEGATIVE_INFINITY;
for (int rangeID = 0; rangeID < numRange; rangeID++) { for (int rangeID = 0; rangeID < numRange; rangeID++) {
@ -1284,6 +1377,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
} }
if (accept) { if (accept) {
expectedCounts[rangeID]++; expectedCounts[rangeID]++;
expectedTopNChildrenCounts[rangeID]++;
minAcceptedValue = Math.min(minAcceptedValue, values[i][j]); minAcceptedValue = Math.min(minAcceptedValue, values[i][j]);
maxAcceptedValue = Math.max(maxAcceptedValue, values[i][j]); maxAcceptedValue = Math.max(maxAcceptedValue, values[i][j]);
break; // ensure each doc can contribute at most 1 count to each range break; // ensure each doc can contribute at most 1 count to each range
@ -1319,6 +1413,8 @@ public class TestRangeFacetCounts extends FacetTestCase {
} }
FacetResult result = facets.getAllChildren("field"); FacetResult result = facets.getAllChildren("field");
assertEquals(numRange, result.labelValues.length); assertEquals(numRange, result.labelValues.length);
FacetResult topNResult = facets.getTopChildren(numRange, "field");
Arrays.sort(expectedTopNChildrenCounts);
for (int rangeID = 0; rangeID < numRange; rangeID++) { for (int rangeID = 0; rangeID < numRange; rangeID++) {
if (VERBOSE) { if (VERBOSE) {
System.out.println(" range " + rangeID + " expectedCount=" + expectedCounts[rangeID]); System.out.println(" range " + rangeID + " expectedCount=" + expectedCounts[rangeID]);
@ -1326,6 +1422,12 @@ public class TestRangeFacetCounts extends FacetTestCase {
LabelAndValue subNode = result.labelValues[rangeID]; LabelAndValue subNode = result.labelValues[rangeID];
assertEquals("r" + rangeID, subNode.label); assertEquals("r" + rangeID, subNode.label);
assertEquals(expectedCounts[rangeID], subNode.value.intValue()); assertEquals(expectedCounts[rangeID], subNode.value.intValue());
// test topNChildren and assert topNResults are sorted by count
if (rangeID < topNResult.labelValues.length) {
LabelAndValue topNsubNode = topNResult.labelValues[rangeID];
assertEquals(
expectedTopNChildrenCounts[numRange - rangeID - 1], topNsubNode.value.intValue());
}
DoubleRange range = ranges[rangeID]; DoubleRange range = ranges[rangeID];
@ -1382,6 +1484,9 @@ public class TestRangeFacetCounts extends FacetTestCase {
assertEquals( assertEquals(
"dim=field path=[] value=16 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", "dim=field path=[] value=16 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.getAllChildren("field").toString()); facets.getAllChildren("field").toString());
assertEquals(
"dim=field path=[] value=16 childCount=4\n 90 or above (8)\n less than 10 (8)\n less than or equal to 10 (8)\n over 90 (8)\n",
facets.getTopChildren(4, "field").toString());
w.close(); w.close();
IOUtils.close(r, d); IOUtils.close(r, d);
@ -1424,6 +1529,9 @@ public class TestRangeFacetCounts extends FacetTestCase {
assertEquals( assertEquals(
"dim=field path=[] value=16 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", "dim=field path=[] value=16 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.getAllChildren("field").toString()); facets.getAllChildren("field").toString());
assertEquals(
"dim=field path=[] value=16 childCount=4\n 90 or above (8)\n less than 10 (8)\n less than or equal to 10 (8)\n over 90 (8)\n",
facets.getTopChildren(4, "field").toString());
w.close(); w.close();
IOUtils.close(r, d); IOUtils.close(r, d);
@ -1599,6 +1707,9 @@ public class TestRangeFacetCounts extends FacetTestCase {
assertEquals( 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", "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.getAllChildren("field").toString()); facets.getAllChildren("field").toString());
assertEquals(
"dim=field path=[] value=3 childCount=5\n < 10 (3)\n < 20 (3)\n < 5 (3)\n < 50 (3)\n < 2 (1)\n",
facets.getTopChildren(5, "field").toString());
assertTrue(fastMatchFilter == null || filterWasUsed.get()); assertTrue(fastMatchFilter == null || filterWasUsed.get());
DrillDownQuery ddq = new DrillDownQuery(config); DrillDownQuery ddq = new DrillDownQuery(config);
@ -1643,6 +1754,9 @@ public class TestRangeFacetCounts extends FacetTestCase {
assertEquals( 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", "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",
dsr.facets.getAllChildren("field").toString()); dsr.facets.getAllChildren("field").toString());
assertEquals(
"dim=field path=[] value=3 childCount=5\n < 10 (3)\n < 20 (3)\n < 5 (3)\n < 50 (3)\n < 2 (1)\n",
dsr.facets.getTopChildren(5, "field").toString());
writer.close(); writer.close();
IOUtils.close(r, dir); IOUtils.close(r, dir);