You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by gs...@apache.org on 2022/06/21 23:48:55 UTC
[lucene] branch main updated: LUCENE-10550: Add getAllChildren functionality to facets (#914)
This is an automated email from the ASF dual-hosted git repository.
gsmiller pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/lucene.git
The following commit(s) were added to refs/heads/main by this push:
new bdcb4b37164 LUCENE-10550: Add getAllChildren functionality to facets (#914)
bdcb4b37164 is described below
commit bdcb4b37164ba07e87e2e987f7fd4c9c50690601
Author: Yuting Gan <44...@users.noreply.github.com>
AuthorDate: Tue Jun 21 16:48:50 2022 -0700
LUCENE-10550: Add getAllChildren functionality to facets (#914)
---
lucene/CHANGES.txt | 2 +-
.../src/java/org/apache/lucene/facet/Facets.java | 7 ++
.../apache/lucene/facet/LongValueFacetCounts.java | 44 +++++--
.../java/org/apache/lucene/facet/MultiFacets.java | 12 ++
.../lucene/facet/StringValueFacetCounts.java | 49 ++++++--
.../lucene/facet/range/RangeFacetCounts.java | 43 +++++--
.../AbstractSortedSetDocValueFacetCounts.java | 70 ++++++++++++
.../DefaultSortedSetDocValuesReaderState.java | 2 +-
.../lucene/facet/taxonomy/FloatTaxonomyFacets.java | 58 ++++++++++
.../lucene/facet/taxonomy/IntTaxonomyFacets.java | 70 ++++++++++++
.../lucene/facet/TestLongValueFacetCounts.java | 71 ++++++++++++
.../lucene/facet/TestMultipleIndexFields.java | 22 ++++
.../lucene/facet/TestStringValueFacetCounts.java | 109 +++++++++++++++---
.../lucene/facet/range/TestRangeFacetCounts.java | 38 +++----
.../sortedset/TestSortedSetDocValuesFacets.java | 126 ++++++++++++++++++++-
.../taxonomy/TestTaxonomyFacetAssociations.java | 41 +++++++
.../facet/taxonomy/TestTaxonomyFacetCounts.java | 71 ++++++++++++
17 files changed, 771 insertions(+), 64 deletions(-)
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index dc6bceb6672..feb5ebb6333 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -77,7 +77,7 @@ API Changes
New Features
---------------------
-(No changes)
+* LUCENE-10550: Add getAllChildren functionality to facets (Yuting Gan)
Improvements
---------------------
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/Facets.java b/lucene/facet/src/java/org/apache/lucene/facet/Facets.java
index a11dd6e8a64..cc59a90dca0 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/Facets.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/Facets.java
@@ -29,6 +29,13 @@ public abstract class Facets {
/** Default constructor. */
public Facets() {}
+ /**
+ * Returns all child labels with non-zero counts under the specified path. Users should make no
+ * assumptions about ordering of the children. Returns null if the specified path doesn't exist or
+ * if this dimension was never seen.
+ */
+ public abstract FacetResult getAllChildren(String dim, String... path) throws IOException;
+
/**
* Returns the topN child labels under the specified path. Returns null if the specified path
* doesn't exist or if this dimension was never seen.
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/LongValueFacetCounts.java b/lucene/facet/src/java/org/apache/lucene/facet/LongValueFacetCounts.java
index 82bf7d65ac4..0a4a7514fb9 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/LongValueFacetCounts.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/LongValueFacetCounts.java
@@ -347,15 +347,35 @@ public class LongValueFacetCounts extends Facets {
}
@Override
- public FacetResult getTopChildren(int topN, String dim, String... path) {
- validateTopN(topN);
- if (dim.equals(field) == false) {
- throw new IllegalArgumentException(
- "invalid dim \"" + dim + "\"; should be \"" + field + "\"");
+ public FacetResult getAllChildren(String dim, String... path) throws IOException {
+ validateDimAndPathForGetChildren(dim, path);
+ List<LabelAndValue> labelValues = new ArrayList<>();
+ for (int i = 0; i < counts.length; i++) {
+ if (counts[i] != 0) {
+ labelValues.add(new LabelAndValue(Long.toString(i), counts[i]));
+ }
}
- if (path.length != 0) {
- throw new IllegalArgumentException("path.length should be 0");
+ if (hashCounts.size() != 0) {
+ for (LongIntCursor c : hashCounts) {
+ int count = c.value;
+ if (count != 0) {
+ labelValues.add(new LabelAndValue(Long.toString(c.key), c.value));
+ }
+ }
}
+
+ return new FacetResult(
+ field,
+ new String[0],
+ totCount,
+ labelValues.toArray(new LabelAndValue[0]),
+ labelValues.size());
+ }
+
+ @Override
+ public FacetResult getTopChildren(int topN, String dim, String... path) {
+ validateTopN(topN);
+ validateDimAndPathForGetChildren(dim, path);
return getTopChildrenSortByCount(topN);
}
@@ -482,6 +502,16 @@ public class LongValueFacetCounts extends Facets {
}
}
+ private void validateDimAndPathForGetChildren(String dim, String... path) {
+ 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");
+ }
+ }
+
@Override
public Number getSpecificValue(String dim, String... path) {
// TODO: should we impl this?
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/MultiFacets.java b/lucene/facet/src/java/org/apache/lucene/facet/MultiFacets.java
index aa57013cada..58222d8b26f 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/MultiFacets.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/MultiFacets.java
@@ -40,6 +40,18 @@ public class MultiFacets extends Facets {
this.defaultFacets = defaultFacets;
}
+ @Override
+ public FacetResult getAllChildren(String dim, String... path) throws IOException {
+ Facets facets = dimToFacets.get(dim);
+ if (facets == null) {
+ if (defaultFacets == null) {
+ throw new IllegalArgumentException("invalid dim \"" + dim + "\"");
+ }
+ facets = defaultFacets;
+ }
+ return facets.getAllChildren(dim, path);
+ }
+
@Override
public FacetResult getTopChildren(int topN, String dim, String... path) throws IOException {
validateTopN(topN);
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/StringValueFacetCounts.java b/lucene/facet/src/java/org/apache/lucene/facet/StringValueFacetCounts.java
index aa82c89c742..55a0bb1ccab 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/StringValueFacetCounts.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/StringValueFacetCounts.java
@@ -19,6 +19,7 @@ package org.apache.lucene.facet;
import com.carrotsearch.hppc.IntIntHashMap;
import com.carrotsearch.hppc.cursors.IntIntCursor;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -130,16 +131,40 @@ public class StringValueFacetCounts extends Facets {
}
}
+ @Override
+ public FacetResult getAllChildren(String dim, String... path) throws IOException {
+ validateDimAndPathForGetChildren(dim, path);
+
+ List<LabelAndValue> labelValues = new ArrayList<>();
+
+ if (sparseCounts != null) {
+ for (IntIntCursor cursor : sparseCounts) {
+ int count = cursor.value;
+ final BytesRef term = docValues.lookupOrd(cursor.key);
+ labelValues.add(new LabelAndValue(term.utf8ToString(), count));
+ }
+ } else {
+ for (int i = 0; i < denseCounts.length; i++) {
+ int count = denseCounts[i];
+ if (count != 0) {
+ final BytesRef term = docValues.lookupOrd(i);
+ labelValues.add(new LabelAndValue(term.utf8ToString(), count));
+ }
+ }
+ }
+
+ return new FacetResult(
+ field,
+ new String[0],
+ totalDocCount,
+ labelValues.toArray(new LabelAndValue[0]),
+ labelValues.size());
+ }
+
@Override
public FacetResult getTopChildren(int topN, String dim, String... path) throws IOException {
validateTopN(topN);
- 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");
- }
+ validateDimAndPathForGetChildren(dim, path);
topN = Math.min(topN, cardinality);
TopOrdAndIntQueue q = null;
@@ -548,4 +573,14 @@ public class StringValueFacetCounts extends Facets {
"the SortedSetDocValuesReaderState provided to this class does not match the reader being searched; you must create a new SortedSetDocValuesReaderState every time you open a new IndexReader");
}
}
+
+ private void validateDimAndPathForGetChildren(String dim, String... path) {
+ 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");
+ }
+ }
}
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/range/RangeFacetCounts.java b/lucene/facet/src/java/org/apache/lucene/facet/range/RangeFacetCounts.java
index 3786fd089c2..1e93ad802b0 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/range/RangeFacetCounts.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/range/RangeFacetCounts.java
@@ -216,16 +216,15 @@ abstract class RangeFacetCounts extends Facets {
totCount -= missingCount;
}
+ /**
+ * {@inheritDoc}
+ *
+ * <p>NOTE: This implementation guarantees that ranges will be returned in the order specified by
+ * the user when calling the constructor.
+ */
@Override
- public FacetResult getTopChildren(int topN, String dim, String... path) {
- validateTopN(topN);
- 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");
- }
+ public FacetResult getAllChildren(String dim, String... path) throws IOException {
+ validateDimAndPathForGetChildren(dim, path);
LabelAndValue[] labelValues = new LabelAndValue[counts.length];
for (int i = 0; i < counts.length; i++) {
labelValues[i] = new LabelAndValue(ranges[i].label, counts[i]);
@@ -233,6 +232,22 @@ abstract class RangeFacetCounts extends Facets {
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
+ public FacetResult getTopChildren(int topN, String dim, String... path) throws IOException {
+ validateTopN(topN);
+ return getAllChildren(dim, path);
+ }
+
@Override
public Number getSpecificValue(String dim, String... path) throws IOException {
// TODO: should we impl this?
@@ -260,4 +275,14 @@ abstract class RangeFacetCounts extends Facets {
}
return b.toString();
}
+
+ private void validateDimAndPathForGetChildren(String dim, String... path) {
+ 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");
+ }
+ }
}
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/sortedset/AbstractSortedSetDocValueFacetCounts.java b/lucene/facet/src/java/org/apache/lucene/facet/sortedset/AbstractSortedSetDocValueFacetCounts.java
index 7edef89aca7..4e930d04a14 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/sortedset/AbstractSortedSetDocValueFacetCounts.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/sortedset/AbstractSortedSetDocValueFacetCounts.java
@@ -72,6 +72,76 @@ abstract class AbstractSortedSetDocValueFacetCounts extends Facets {
return createFacetResult(topChildrenForPath, dim, path);
}
+ @Override
+ public FacetResult getAllChildren(String dim, String... path) throws IOException {
+ FacetsConfig.DimConfig dimConfig = stateConfig.getDimConfig(dim);
+
+ // Determine the path ord and resolve an iterator to its immediate children. The logic for this
+ // depends on whether-or-not the dimension is configured as hierarchical:
+ final int pathOrd;
+ final PrimitiveIterator.OfInt childIterator;
+ if (dimConfig.hierarchical) {
+ DimTree dimTree = state.getDimTree(dim);
+ if (path.length > 0) {
+ pathOrd = (int) dv.lookupTerm(new BytesRef(FacetsConfig.pathToString(dim, path)));
+ } else {
+ // If there's no path, this is a little more efficient to just look up the dim:
+ pathOrd = dimTree.dimStartOrd;
+ }
+ if (pathOrd < 0) {
+ // path was never indexed
+ return null;
+ }
+ childIterator = dimTree.iterator(pathOrd);
+ } else {
+ if (path.length > 0) {
+ throw new IllegalArgumentException(
+ "Field is not configured as hierarchical, path should be 0 length");
+ }
+ OrdRange ordRange = state.getOrdRange(dim);
+ if (ordRange == null) {
+ // means dimension was never indexed
+ return null;
+ }
+ pathOrd = ordRange.start;
+ childIterator = ordRange.iterator();
+ if (dimConfig.multiValued && dimConfig.requireDimCount) {
+ // If the dim is multi-valued and requires dim counts, we know we've explicitly indexed
+ // the dimension and we need to skip past it so the iterator is positioned on the first
+ // child:
+ childIterator.next();
+ }
+ }
+ // Compute the actual results:
+ int pathCount = 0;
+ List<LabelAndValue> labelValues = new ArrayList<>();
+ while (childIterator.hasNext()) {
+ int ord = childIterator.next();
+ int count = getCount(ord);
+ if (count > 0) {
+ pathCount += count;
+ final BytesRef term = dv.lookupOrd(ord);
+ String[] parts = FacetsConfig.stringToPath(term.utf8ToString());
+ labelValues.add(new LabelAndValue(parts[parts.length - 1], count));
+ }
+ }
+
+ if (dimConfig.hierarchical) {
+ pathCount = getCount(pathOrd);
+ } else {
+ // see if pathCount is actually reliable or needs to be reset
+ if (dimConfig.multiValued) {
+ if (dimConfig.requireDimCount) {
+ pathCount = getCount(pathOrd);
+ } else {
+ pathCount = -1; // pathCount is inaccurate at this point, so set it to -1
+ }
+ }
+ }
+ return new FacetResult(
+ dim, path, pathCount, labelValues.toArray(new LabelAndValue[0]), labelValues.size());
+ }
+
@Override
public Number getSpecificValue(String dim, String... path) throws IOException {
if (stateConfig.getDimConfig(dim).hierarchical == false && path.length != 1) {
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/sortedset/DefaultSortedSetDocValuesReaderState.java b/lucene/facet/src/java/org/apache/lucene/facet/sortedset/DefaultSortedSetDocValuesReaderState.java
index cf45f835654..21e6c031b7a 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/sortedset/DefaultSortedSetDocValuesReaderState.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/sortedset/DefaultSortedSetDocValuesReaderState.java
@@ -381,7 +381,7 @@ public class DefaultSortedSetDocValuesReaderState extends SortedSetDocValuesRead
public DimTree getDimTree(String dim) {
if (config.getDimConfig(dim).hierarchical == false) {
throw new UnsupportedOperationException(
- "This opperation is only supported for hierarchical facets");
+ "This operation is only supported for hierarchical facets");
}
return prefixToDimTree.get(dim);
}
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/FloatTaxonomyFacets.java b/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/FloatTaxonomyFacets.java
index 8c9853d1641..d8381ae51dc 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/FloatTaxonomyFacets.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/FloatTaxonomyFacets.java
@@ -17,6 +17,7 @@
package org.apache.lucene.facet.taxonomy;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -101,6 +102,63 @@ abstract class FloatTaxonomyFacets extends TaxonomyFacets {
return values[ord];
}
+ @Override
+ public FacetResult getAllChildren(String dim, String... path) throws IOException {
+ DimConfig dimConfig = verifyDim(dim);
+ FacetLabel cp = new FacetLabel(dim, path);
+ int dimOrd = taxoReader.getOrdinal(cp);
+ if (dimOrd == -1) {
+ return null;
+ }
+
+ int[] children = getChildren();
+ int[] siblings = getSiblings();
+
+ int ord = children[dimOrd];
+ float aggregatedValue = 0;
+
+ List<Integer> ordinals = new ArrayList<>();
+ List<Float> ordValues = new ArrayList<>();
+
+ while (ord != TaxonomyReader.INVALID_ORDINAL) {
+ if (values[ord] > 0) {
+ aggregatedValue = aggregationFunction.aggregate(aggregatedValue, values[ord]);
+ ordinals.add(ord);
+ ordValues.add(values[ord]);
+ }
+ ord = siblings[ord];
+ }
+
+ if (aggregatedValue == 0) {
+ return null;
+ }
+
+ if (dimConfig.multiValued) {
+ if (dimConfig.requireDimCount) {
+ aggregatedValue = values[dimOrd];
+ } else {
+ // Our sum'd count is not correct, in general:
+ aggregatedValue = -1;
+ }
+ } else {
+ // Our sum'd dim count is accurate, so we keep it
+ }
+
+ // TODO: It would be nice if TaxonomyReader could directly support List in addition to an array
+ // so that we don't need to do this copy just to look up bulk paths
+ int[] ordinalArray = new int[ordinals.size()];
+ for (int i = 0; i < ordinals.size(); i++) {
+ ordinalArray[i] = ordinals.get(i);
+ }
+
+ LabelAndValue[] labelValues = new LabelAndValue[ordValues.size()];
+ FacetLabel[] bulkPath = taxoReader.getBulkPath(ordinalArray);
+ for (int i = 0; i < labelValues.length; i++) {
+ labelValues[i] = new LabelAndValue(bulkPath[i].components[cp.length], ordValues.get(i));
+ }
+ return new FacetResult(dim, path, aggregatedValue, labelValues, ordinals.size());
+ }
+
@Override
public FacetResult getTopChildren(int topN, String dim, String... path) throws IOException {
validateTopN(topN);
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/IntTaxonomyFacets.java b/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/IntTaxonomyFacets.java
index 3992cdc3357..9c40079c4fa 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/IntTaxonomyFacets.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/IntTaxonomyFacets.java
@@ -19,6 +19,7 @@ package org.apache.lucene.facet.taxonomy;
import com.carrotsearch.hppc.IntIntHashMap;
import com.carrotsearch.hppc.cursors.IntIntCursor;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -163,6 +164,75 @@ abstract class IntTaxonomyFacets extends TaxonomyFacets {
return getValue(ord);
}
+ @Override
+ public FacetResult getAllChildren(String dim, String... path) throws IOException {
+ DimConfig dimConfig = verifyDim(dim);
+ FacetLabel cp = new FacetLabel(dim, path);
+ int dimOrd = taxoReader.getOrdinal(cp);
+ if (dimOrd == -1) {
+ return null;
+ }
+
+ int aggregatedValue = 0;
+
+ List<Integer> ordinals = new ArrayList<>();
+ List<Integer> ordValues = new ArrayList<>();
+
+ if (sparseValues != null) {
+ for (IntIntCursor c : sparseValues) {
+ int value = c.value;
+ int ord = c.key;
+ if (parents[ord] == dimOrd && value > 0) {
+ aggregatedValue = aggregationFunction.aggregate(aggregatedValue, value);
+ ordinals.add(ord);
+ ordValues.add(value);
+ }
+ }
+ } else {
+ int[] children = getChildren();
+ int[] siblings = getSiblings();
+ int ord = children[dimOrd];
+ while (ord != TaxonomyReader.INVALID_ORDINAL) {
+ int value = values[ord];
+ if (value > 0) {
+ aggregatedValue = aggregationFunction.aggregate(aggregatedValue, value);
+ ordinals.add(ord);
+ ordValues.add(value);
+ }
+ ord = siblings[ord];
+ }
+ }
+
+ if (aggregatedValue == 0) {
+ return null;
+ }
+
+ if (dimConfig.multiValued) {
+ if (dimConfig.requireDimCount) {
+ aggregatedValue = getValue(dimOrd);
+ } else {
+ // Our sum'd value is not correct, in general:
+ aggregatedValue = -1;
+ }
+ } else {
+ // Our sum'd dim value is accurate, so we keep it
+ }
+
+ // TODO: It would be nice if TaxonomyReader could directly support List in addition to an array
+ // so that we don't need to do this copy just to look up bulk paths
+ int[] ordinalArray = new int[ordinals.size()];
+ for (int i = 0; i < ordinals.size(); i++) {
+ ordinalArray[i] = ordinals.get(i);
+ }
+
+ LabelAndValue[] labelValues = new LabelAndValue[ordValues.size()];
+ FacetLabel[] bulkPath = taxoReader.getBulkPath(ordinalArray);
+ for (int i = 0; i < ordValues.size(); i++) {
+ labelValues[i] = new LabelAndValue(bulkPath[i].components[cp.length], ordValues.get(i));
+ }
+ return new FacetResult(dim, path, aggregatedValue, labelValues, ordinals.size());
+ }
+
@Override
public FacetResult getTopChildren(int topN, String dim, String... path) throws IOException {
validateTopN(topN);
diff --git a/lucene/facet/src/test/org/apache/lucene/facet/TestLongValueFacetCounts.java b/lucene/facet/src/test/org/apache/lucene/facet/TestLongValueFacetCounts.java
index eaf8d64634c..90fe2d464fa 100644
--- a/lucene/facet/src/test/org/apache/lucene/facet/TestLongValueFacetCounts.java
+++ b/lucene/facet/src/test/org/apache/lucene/facet/TestLongValueFacetCounts.java
@@ -69,6 +69,18 @@ public class TestLongValueFacetCounts extends LuceneTestCase {
"dim=field path=[] value=101 childCount=6\n 0 (20)\n 1 (20)\n 2 (20)\n 3 (20)\n "
+ "4 (20)\n 9223372036854775807 (1)\n",
result.toString());
+
+ FacetResult topChildrenResult = facets.getTopChildren(2, "field");
+ assertEquals(
+ "dim=field path=[] value=101 childCount=6\n 0 (20)\n 1 (20)\n",
+ topChildrenResult.toString());
+
+ FacetResult allChildrenResult = facets.getAllChildren("field");
+ assertEquals(
+ "dim=field path=[] value=101 childCount=6\n 0 (20)\n 1 (20)\n 2 (20)\n 3 (20)\n "
+ + "4 (20)\n 9223372036854775807 (1)\n",
+ allChildrenResult.toString());
+
r.close();
d.close();
}
@@ -94,6 +106,11 @@ public class TestLongValueFacetCounts extends LuceneTestCase {
FacetResult result = facets.getAllChildrenSortByValue();
assertEquals("dim=field path=[] value=9 childCount=2\n 0 (4)\n 1 (5)\n", result.toString());
+ result = facets.getTopChildren(10, "field");
+ assertEquals("dim=field path=[] value=9 childCount=2\n 1 (5)\n 0 (4)\n", result.toString());
+ result = facets.getAllChildren("field");
+ assertEquals("dim=field path=[] value=9 childCount=2\n 0 (4)\n 1 (5)\n", result.toString());
+
r.close();
d.close();
}
@@ -116,6 +133,22 @@ public class TestLongValueFacetCounts extends LuceneTestCase {
LongValueFacetCounts facets = new LongValueFacetCounts("field", fc);
FacetResult result = facets.getAllChildrenSortByValue();
+ assertEquals(
+ "dim=field path=[] value=3 childCount=3\n 9223372036854775805 (1)\n "
+ + "9223372036854775806 (1)\n 9223372036854775807 (1)\n",
+ result.toString());
+
+ // test getAllChildren
+ result = facets.getAllChildren("field");
+
+ // since we have no insight into the value order in the hashMap, we sort labels by value and
+ // count in
+ // ascending order in order to compare with expected results
+ Arrays.sort(
+ result.labelValues,
+ Comparator.comparing((LabelAndValue a) -> a.label)
+ .thenComparingLong(a -> a.value.longValue()));
+
assertEquals(
"dim=field path=[] value=3 childCount=3\n 9223372036854775805 (1)\n "
+ "9223372036854775806 (1)\n 9223372036854775807 (1)\n",
@@ -308,6 +341,24 @@ public class TestLongValueFacetCounts extends LuceneTestCase {
actual,
Integer.MAX_VALUE);
+ // test getAllChildren
+ expectedCounts.sort(
+ Comparator.comparing((Map.Entry<Long, Integer> a) -> a.getKey())
+ .thenComparingLong(Map.Entry::getValue));
+ FacetResult allChildren = facetCounts.getAllChildren("field");
+ // sort labels by value, count in ascending order
+ Arrays.sort(
+ allChildren.labelValues,
+ Comparator.comparing((LabelAndValue a) -> a.label)
+ .thenComparingLong(a -> a.value.longValue()));
+ assertSame(
+ "test getAllChildren",
+ expectedCounts,
+ expectedChildCount,
+ docCount - missingCount,
+ actual,
+ Integer.MAX_VALUE);
+
// sort by count
expectedCounts.sort(
(a, b) -> {
@@ -553,6 +604,24 @@ public class TestLongValueFacetCounts extends LuceneTestCase {
actual,
Integer.MAX_VALUE);
+ // test getAllChildren
+ expectedCounts.sort(
+ Comparator.comparing((Map.Entry<Long, Integer> a) -> a.getKey())
+ .thenComparingLong(Map.Entry::getValue));
+ FacetResult allChildren = facetCounts.getAllChildren("field");
+ // sort labels by value, count in ascending order
+ Arrays.sort(
+ allChildren.labelValues,
+ Comparator.comparing((LabelAndValue a) -> a.label)
+ .thenComparingLong(a -> a.value.longValue()));
+ assertSame(
+ "test getAllChildren",
+ expectedCounts,
+ expectedChildCount,
+ expectedTotalCount,
+ actual,
+ Integer.MAX_VALUE);
+
// sort by count
expectedCounts.sort(
(a, b) -> {
@@ -736,6 +805,8 @@ public class TestLongValueFacetCounts extends LuceneTestCase {
for (LabelAndValue labelAndValue : fr.labelValues) {
assert labelAndValue.value.equals(1);
}
+ FacetResult result = facetCounts.getAllChildren("field");
+ assertEquals("dim=field path=[] value=2 childCount=2\n 42 (1)\n 43 (1)\n", result.toString());
r.close();
dir.close();
diff --git a/lucene/facet/src/test/org/apache/lucene/facet/TestMultipleIndexFields.java b/lucene/facet/src/test/org/apache/lucene/facet/TestMultipleIndexFields.java
index 89cdc6fad32..e1c2e523491 100644
--- a/lucene/facet/src/test/org/apache/lucene/facet/TestMultipleIndexFields.java
+++ b/lucene/facet/src/test/org/apache/lucene/facet/TestMultipleIndexFields.java
@@ -17,6 +17,8 @@
package org.apache.lucene.facet;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import org.apache.lucene.document.Document;
@@ -294,12 +296,21 @@ public class TestMultipleIndexFields extends FacetTestCase {
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=[] value=5 childCount=2\n Punk (1)\n Rock & Pop (4)\n",
+ sortAllChildren(facets.getAllChildren("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=Band path=[Rock & Pop] value=4 childCount=4\n Dave Matthews Band (1)\n REM (1)\n The Beatles (1)\n U2 (1)\n",
+ sortAllChildren(facets.getAllChildren("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());
+ assertEquals(
+ "dim=Author path=[] value=3 childCount=3\n Kurt Vonnegut (1)\n Mark Twain (1)\n Stephen King (1)\n",
+ sortAllChildren(facets.getAllChildren("Author")).toString());
}
private FacetsCollector performSearch(TaxonomyReader tr, IndexReader ir, IndexSearcher searcher)
@@ -318,4 +329,15 @@ public class TestMultipleIndexFields extends FacetTestCase {
iw.addDocument(config.build(tw, doc));
}
}
+
+ // since we have no insight into the ordinals assigned to the values, we sort labels by value and
+ // count in
+ // ascending order in order to compare with expected results
+ private static FacetResult sortAllChildren(FacetResult allChildrenResult) {
+ Arrays.sort(
+ allChildrenResult.labelValues,
+ Comparator.comparing((LabelAndValue a) -> a.label)
+ .thenComparingLong(a -> a.value.longValue()));
+ return allChildrenResult;
+ }
}
diff --git a/lucene/facet/src/test/org/apache/lucene/facet/TestStringValueFacetCounts.java b/lucene/facet/src/test/org/apache/lucene/facet/TestStringValueFacetCounts.java
index ed0716201fd..7b4dd8097cf 100644
--- a/lucene/facet/src/test/org/apache/lucene/facet/TestStringValueFacetCounts.java
+++ b/lucene/facet/src/test/org/apache/lucene/facet/TestStringValueFacetCounts.java
@@ -19,6 +19,7 @@ package org.apache.lucene.facet;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -72,7 +73,9 @@ public class TestStringValueFacetCounts extends FacetTestCase {
IndexSearcher searcher = newSearcher(writer.getReader());
writer.close();
- checkFacetResult(expectedCounts, expectedTotalDocCount, searcher, 10, 2, 1, 0);
+ StringDocValuesReaderState state =
+ new StringDocValuesReaderState(searcher.getIndexReader(), "field");
+ checkTopNFacetResult(expectedCounts, expectedTotalDocCount, searcher, state, 10, 2, 1, 0);
IOUtils.close(searcher.getIndexReader(), dir);
}
@@ -93,6 +96,11 @@ public class TestStringValueFacetCounts extends FacetTestCase {
doc.add(new SortedSetDocValuesField("field", new BytesRef("foo")));
writer.addDocument(doc);
+ doc = new Document();
+ doc.add(new StringField("id", "2", Field.Store.NO));
+ doc.add(new SortedSetDocValuesField("field", new BytesRef("bar")));
+ writer.addDocument(doc);
+
writer.deleteDocuments(new Term("id", "0"));
IndexSearcher searcher = newSearcher(writer.getReader());
@@ -103,9 +111,17 @@ public class TestStringValueFacetCounts extends FacetTestCase {
StringValueFacetCounts facets = new StringValueFacetCounts(state);
assertEquals(
- "dim=field path=[] value=1 childCount=1\n foo (1)",
+ "dim=field path=[] value=2 childCount=2\n bar (1)",
+ facets.getTopChildren(1, "field").toString().trim());
+
+ assertEquals(
+ "dim=field path=[] value=2 childCount=2\n bar (1)\n foo (1)",
facets.getTopChildren(10, "field").toString().trim());
+ assertEquals(
+ "dim=field path=[] value=2 childCount=2\n bar (1)\n foo (1)",
+ facets.getAllChildren("field").toString().trim());
+
IOUtils.close(searcher.getIndexReader(), dir);
}
@@ -140,7 +156,11 @@ public class TestStringValueFacetCounts extends FacetTestCase {
IndexSearcher searcher = newSearcher(writer.getReader());
writer.close();
- checkFacetResult(expectedCounts, expectedTotalDocCount, searcher, 10, 2, 1, 0);
+ StringDocValuesReaderState state =
+ new StringDocValuesReaderState(searcher.getIndexReader(), "field");
+
+ checkTopNFacetResult(expectedCounts, expectedTotalDocCount, searcher, state, 10, 2, 1, 0);
+ checkAllChildrenFacetResult(expectedCounts, expectedTotalDocCount, searcher, state);
IOUtils.close(searcher.getIndexReader(), dir);
}
@@ -170,7 +190,11 @@ public class TestStringValueFacetCounts extends FacetTestCase {
IndexSearcher searcher = newSearcher(writer.getReader());
writer.close();
- checkFacetResult(expectedCounts, expectedTotalDocCount, searcher, 10, 2, 1, 0);
+ StringDocValuesReaderState state =
+ new StringDocValuesReaderState(searcher.getIndexReader(), "field");
+
+ checkTopNFacetResult(expectedCounts, expectedTotalDocCount, searcher, state, 10, 2, 1, 0);
+ checkAllChildrenFacetResult(expectedCounts, expectedTotalDocCount, searcher, state);
IOUtils.close(searcher.getIndexReader(), dir);
}
@@ -179,7 +203,7 @@ public class TestStringValueFacetCounts extends FacetTestCase {
Directory dir = newDirectory();
RandomIndexWriter writer = new RandomIndexWriter(random(), dir);
- Map<String, Integer> expectedCounts = new HashMap<>();
+ Map<String, Integer> expectedValueCounts = new HashMap<>();
// Create two segments, each with only one doc that has a large number of SSDV field values.
// This ensures "sparse" counting will occur in StringValueFacetCounts (i.e., small number
@@ -187,7 +211,7 @@ public class TestStringValueFacetCounts extends FacetTestCase {
Document doc = new Document();
for (int i = 0; i < 100; i++) {
doc.add(new SortedSetDocValuesField("field", new BytesRef("foo_" + i)));
- expectedCounts.put("foo_" + i, 1);
+ expectedValueCounts.put("foo_" + i, 1);
}
writer.addDocument(doc);
writer.commit();
@@ -195,7 +219,7 @@ public class TestStringValueFacetCounts extends FacetTestCase {
doc = new Document();
for (int i = 0; i < 100; i++) {
doc.add(new SortedSetDocValuesField("field", new BytesRef("bar_" + i)));
- expectedCounts.put("bar_" + i, 1);
+ expectedValueCounts.put("bar_" + i, 1);
}
writer.addDocument(doc);
@@ -204,7 +228,11 @@ public class TestStringValueFacetCounts extends FacetTestCase {
IndexSearcher searcher = newSearcher(writer.getReader());
writer.close();
- checkFacetResult(expectedCounts, expectedTotalDocCount, searcher, 10, 2, 1, 0);
+ StringDocValuesReaderState state =
+ new StringDocValuesReaderState(searcher.getIndexReader(), "field");
+
+ checkTopNFacetResult(expectedValueCounts, expectedTotalDocCount, searcher, state, 10, 2, 1, 0);
+ checkAllChildrenFacetResult(expectedValueCounts, expectedTotalDocCount, searcher, state);
IOUtils.close(searcher.getIndexReader(), dir);
}
@@ -236,7 +264,11 @@ public class TestStringValueFacetCounts extends FacetTestCase {
IndexSearcher searcher = newSearcher(writer.getReader());
writer.close();
- checkFacetResult(expectedCounts, expectedTotalDocCount, searcher, 10, 2, 1, 0);
+ StringDocValuesReaderState state =
+ new StringDocValuesReaderState(searcher.getIndexReader(), "field");
+
+ checkTopNFacetResult(expectedCounts, expectedTotalDocCount, searcher, state, 10, 2, 1, 0);
+ checkAllChildrenFacetResult(expectedCounts, expectedTotalDocCount, searcher, state);
IOUtils.close(searcher.getIndexReader(), dir);
}
@@ -322,22 +354,24 @@ public class TestStringValueFacetCounts extends FacetTestCase {
topNs[i] = atLeast(1);
}
- checkFacetResult(expected, expectedTotalDocCount, searcher, topNs);
+ StringDocValuesReaderState state =
+ new StringDocValuesReaderState(searcher.getIndexReader(), "field");
+
+ checkTopNFacetResult(expected, expectedTotalDocCount, searcher, state, topNs);
+ checkAllChildrenFacetResult(expected, expectedTotalDocCount, searcher, state);
IOUtils.close(searcher.getIndexReader(), dir);
}
}
- private void checkFacetResult(
+ private void checkTopNFacetResult(
Map<String, Integer> expectedCounts,
int expectedTotalDocsWithValue,
IndexSearcher searcher,
+ StringDocValuesReaderState state,
int... topNs)
throws IOException {
- StringDocValuesReaderState state =
- new StringDocValuesReaderState(searcher.getIndexReader(), "field");
-
FacetsCollector c = searcher.search(new MatchAllDocsQuery(), new FacetsCollectorManager());
for (int topN : topNs) {
@@ -437,4 +471,51 @@ public class TestStringValueFacetCounts extends FacetTestCase {
}
}
}
+
+ private void checkAllChildrenFacetResult(
+ Map<String, Integer> expectedValueCounts,
+ int expectedTotalDocsWithValue,
+ IndexSearcher searcher,
+ StringDocValuesReaderState state)
+ throws IOException {
+
+ FacetsCollector c = searcher.search(new MatchAllDocsQuery(), new FacetsCollectorManager());
+
+ StringValueFacetCounts facets;
+ // should get the same result whether-or-not we provide a FacetsCollector since it's doing
+ // a MatchAllDocsQuery:
+ if (random().nextBoolean()) {
+ facets = new StringValueFacetCounts(state, c);
+ } else {
+ facets = new StringValueFacetCounts(state);
+ }
+
+ List<Map.Entry<String, Integer>> expectedCountsSortedByValue =
+ new ArrayList<>(expectedValueCounts.entrySet());
+
+ // sort expected counts by value, count
+ expectedCountsSortedByValue.sort(
+ Comparator.comparing((Map.Entry<String, Integer> a) -> a.getKey())
+ .thenComparingInt(Map.Entry::getValue));
+
+ FacetResult facetResult = facets.getAllChildren("field");
+ assertEquals(expectedTotalDocsWithValue, facetResult.value);
+
+ // since we have no insight into the ordinals assigned to the values, we sort labels by value
+ // and count in
+ // ascending order in order to compare with expected results
+ Arrays.sort(
+ facetResult.labelValues,
+ Comparator.comparing((LabelAndValue a) -> a.label)
+ .thenComparingLong(a -> a.value.longValue()));
+
+ for (int i = 0; i < expectedCountsSortedByValue.size(); i++) {
+ String expectedKey = expectedCountsSortedByValue.get(i).getKey();
+ int expectedValue = expectedCountsSortedByValue.get(i).getValue();
+ assertEquals(expectedKey, facetResult.labelValues[i].label);
+ assertEquals(expectedValue, facetResult.labelValues[i].value);
+ // make sure getSpecificValue reports the same count
+ assertEquals(expectedValue, facets.getSpecificValue("field", expectedKey));
+ }
+ }
}
diff --git a/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java b/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java
index cdfdefd539b..e33556337b4 100644
--- a/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java
+++ b/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java
@@ -99,7 +99,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
new LongRange("90 or above", 90L, true, 100L, false),
new LongRange("over 1000", 1000L, false, Long.MAX_VALUE, true));
- FacetResult result = facets.getTopChildren(10, "field");
+ FacetResult result = facets.getAllChildren("field");
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",
result.toString());
@@ -151,7 +151,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
new LongRange("90 or above", 90L, true, 100L, false),
new LongRange("over 1000", 1000L, false, Long.MAX_VALUE, true));
- FacetResult result = facets.getTopChildren(10, "field");
+ FacetResult result = facets.getAllChildren("field");
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",
result.toString());
@@ -201,7 +201,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
new LongRange("90 or above", 90L, true, 100L, false),
new LongRange("over 1000", 1000L, false, Long.MAX_VALUE, true));
- FacetResult result = facets.getTopChildren(10, "field");
+ FacetResult result = facets.getAllChildren("field");
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",
result.toString());
@@ -327,7 +327,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
new LongRange("all2", Long.MIN_VALUE, true, Long.MAX_VALUE, false),
new LongRange("all3", Long.MIN_VALUE, false, Long.MAX_VALUE, false));
- FacetResult result = facets.getTopChildren(10, "field");
+ FacetResult result = facets.getAllChildren("field");
assertEquals(
"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());
@@ -364,7 +364,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
new LongRange("20-30", 20L, true, 30L, true),
new LongRange("30-40", 30L, true, 40L, true));
- FacetResult result = facets.getTopChildren(10, "field");
+ FacetResult result = facets.getAllChildren("field");
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",
result.toString());
@@ -391,7 +391,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
Facets facets = new LongRangeFacetCounts("field", fc);
- FacetResult result = facets.getTopChildren(10, "field");
+ FacetResult result = facets.getAllChildren("field");
assertEquals("dim=field path=[] value=0 childCount=0\n", result.toString());
r.close();
@@ -420,7 +420,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
Facets facets = new LongRangeFacetCounts("field", fc);
- FacetResult result = facets.getTopChildren(10, "field");
+ FacetResult result = facets.getAllChildren("field");
assertEquals("dim=field path=[] value=0 childCount=0\n", result.toString());
r.close();
@@ -574,7 +574,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
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",
- facets.getTopChildren(10, "field").toString());
+ facets.getAllChildren("field").toString());
w.close();
IOUtils.close(r, d);
}
@@ -610,7 +610,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
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",
- facets.getTopChildren(10, "field").toString());
+ facets.getAllChildren("field").toString());
w.close();
IOUtils.close(r, d);
}
@@ -656,7 +656,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
new DoubleRange("90 or above", 90.0, true, 100.0, false),
new DoubleRange("over 1000", 1000.0, false, Double.POSITIVE_INFINITY, false));
- FacetResult result = facets.getTopChildren(10, "field");
+ FacetResult result = facets.getAllChildren("field");
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",
result.toString());
@@ -797,7 +797,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
new LongRangeFacetCounts(
"field", MultiLongValuesSource.fromSingleValued(vs), sfc, fastMatchQuery, ranges);
}
- FacetResult result = facets.getTopChildren(10, "field");
+ FacetResult result = facets.getAllChildren("field");
assertEquals(numRange, result.labelValues.length);
for (int rangeID = 0; rangeID < numRange; rangeID++) {
if (VERBOSE) {
@@ -823,7 +823,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
} else {
MultiLongValuesSource vs = MultiLongValuesSource.fromLongField("field");
Facets facets = new LongRangeFacetCounts("field", vs, sfc, fastMatchQuery, ranges);
- FacetResult result = facets.getTopChildren(10, "field");
+ FacetResult result = facets.getAllChildren("field");
assertEquals(numRange, result.labelValues.length);
for (int rangeID = 0; rangeID < numRange; rangeID++) {
if (VERBOSE) {
@@ -989,7 +989,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
new LongRangeFacetCounts(
"field", (MultiLongValuesSource) null, sfc, fastMatchQuery, ranges);
}
- FacetResult result = facets.getTopChildren(10, "field");
+ FacetResult result = facets.getAllChildren("field");
assertEquals(numRange, result.labelValues.length);
for (int rangeID = 0; rangeID < numRange; rangeID++) {
if (VERBOSE) {
@@ -1147,7 +1147,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
} else {
facets = new DoubleRangeFacetCounts("field", mvs, sfc, fastMatchFilter, ranges);
}
- FacetResult result = facets.getTopChildren(10, "field");
+ FacetResult result = facets.getAllChildren("field");
assertEquals(numRange, result.labelValues.length);
for (int rangeID = 0; rangeID < numRange; rangeID++) {
if (VERBOSE) {
@@ -1314,7 +1314,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
new DoubleRangeFacetCounts(
"field", (MultiDoubleValuesSource) null, sfc, fastMatchFilter, ranges);
}
- FacetResult result = facets.getTopChildren(10, "field");
+ FacetResult result = facets.getAllChildren("field");
assertEquals(numRange, result.labelValues.length);
for (int rangeID = 0; rangeID < numRange; rangeID++) {
if (VERBOSE) {
@@ -1378,7 +1378,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
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",
- facets.getTopChildren(10, "field").toString());
+ facets.getAllChildren("field").toString());
w.close();
IOUtils.close(r, d);
@@ -1420,7 +1420,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
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",
- facets.getTopChildren(10, "field").toString());
+ facets.getAllChildren("field").toString());
w.close();
IOUtils.close(r, d);
@@ -1592,7 +1592,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
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());
+ facets.getAllChildren("field").toString());
assertTrue(fastMatchFilter == null || filterWasUsed.get());
DrillDownQuery ddq = new DrillDownQuery(config);
@@ -1636,7 +1636,7 @@ public class TestRangeFacetCounts extends FacetTestCase {
assertEquals(1, dsr.hits.totalHits.value);
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",
- dsr.facets.getTopChildren(10, "field").toString());
+ dsr.facets.getAllChildren("field").toString());
writer.close();
IOUtils.close(r, dir);
diff --git a/lucene/facet/src/test/org/apache/lucene/facet/sortedset/TestSortedSetDocValuesFacets.java b/lucene/facet/src/test/org/apache/lucene/facet/sortedset/TestSortedSetDocValuesFacets.java
index b893e3884fe..37a2311ed85 100644
--- a/lucene/facet/src/test/org/apache/lucene/facet/sortedset/TestSortedSetDocValuesFacets.java
+++ b/lucene/facet/src/test/org/apache/lucene/facet/sortedset/TestSortedSetDocValuesFacets.java
@@ -105,6 +105,12 @@ public class TestSortedSetDocValuesFacets extends FacetTestCase {
"dim=b path=[] value=2 childCount=2\n buzz (2)\n baz (1)\n",
facets.getTopChildren(10, "b").toString());
+ // test getAllChildren
+ // value for dim a should be -1 since it's multivalued but doesn't require dim counts:
+ assertEquals(
+ "dim=a path=[] value=-1 childCount=3\n bar (1)\n foo (2)\n zoo (1)\n",
+ facets.getAllChildren("a").toString());
+
// test getAllDims
List<FacetResult> results = facets.getAllDims(10);
assertEquals(2, results.size());
@@ -354,12 +360,18 @@ public class TestSortedSetDocValuesFacets extends FacetTestCase {
assertEquals(
"dim=a path=[] value=2 childCount=3\n foo (2)\n bar (1)\n zoo (1)\n",
facets.getTopChildren(10, "a").toString());
+ assertEquals(
+ "dim=a path=[] value=2 childCount=3\n bar (1)\n foo (2)\n zoo (1)\n",
+ facets.getAllChildren("a").toString());
assertEquals(
"dim=b path=[] value=1 childCount=1\n baz (1)\n",
facets.getTopChildren(10, "b").toString());
assertEquals(
"dim=c path=[buzz] value=2 childCount=3\n bif (2)\n bee (1)\n biz (1)\n",
facets.getTopChildren(10, "c", "buzz").toString());
+ assertEquals(
+ "dim=c path=[buzz] value=2 childCount=3\n bee (1)\n bif (2)\n biz (1)\n",
+ facets.getAllChildren("c", "buzz").toString());
assertEquals(
"dim=c path=[buzz, bif] value=2 childCount=1\n baf (2)\n",
facets.getTopChildren(10, "c", "buzz", "bif").toString());
@@ -371,7 +383,9 @@ public class TestSortedSetDocValuesFacets extends FacetTestCase {
// ... but not on non-hierarchical dims:
expectThrows(
IllegalArgumentException.class, () -> facets.getSpecificValue("a", "foo", "bar)"));
-
+ assertEquals(
+ "dim=c path=[buzz, bif] value=2 childCount=1\n baf (2)\n",
+ facets.getAllChildren("c", "buzz", "bif").toString());
// DrillDown:
DrillDownQuery q = new DrillDownQuery(config);
q.add("a", "foo");
@@ -427,6 +441,10 @@ public class TestSortedSetDocValuesFacets extends FacetTestCase {
"dim=a path=[] value=1 childCount=1\n bar (1)\n",
facets.getTopChildren(10, "a").toString());
+ assertEquals(
+ "dim=a path=[] value=1 childCount=1\n bar (1)\n",
+ facets.getAllChildren("a").toString());
+
// test topNChildren = 0
Facets finalFacets = facets;
expectThrows(
@@ -487,6 +505,18 @@ public class TestSortedSetDocValuesFacets extends FacetTestCase {
doc.add(new SortedSetDocValuesFacetField("b", "buzz", "baz"));
writer.addDocument(config.build(doc));
+ doc = new Document();
+ doc.add(new StringField("id", "2", Field.Store.NO));
+ doc.add(new SortedSetDocValuesFacetField("a", "buz"));
+ doc.add(new SortedSetDocValuesFacetField("b", "bar", "foo"));
+ writer.addDocument(config.build(doc));
+
+ doc = new Document();
+ doc.add(new StringField("id", "2", Field.Store.NO));
+ doc.add(new SortedSetDocValuesFacetField("a", "baz"));
+ doc.add(new SortedSetDocValuesFacetField("b", "bar"));
+ writer.addDocument(config.build(doc));
+
writer.deleteDocuments(new Term("id", "0"));
// NRT open
@@ -500,11 +530,18 @@ public class TestSortedSetDocValuesFacets extends FacetTestCase {
Facets facets = new SortedSetDocValuesFacetCounts(state);
assertEquals(
- "dim=a path=[] value=1 childCount=1\n bar (1)\n",
+ "dim=a path=[] value=3 childCount=3\n bar (1)\n baz (1)\n buz (1)\n",
facets.getTopChildren(10, "a").toString());
assertEquals(
"dim=b path=[buzz] value=1 childCount=1\n baz (1)\n",
facets.getTopChildren(10, "b", "buzz").toString());
+ assertEquals(
+ "dim=a path=[] value=3 childCount=3\n bar (1)\n baz (1)\n buz (1)\n",
+ facets.getAllChildren("a").toString());
+ assertEquals(
+ "dim=b path=[] value=3 childCount=2\n bar (2)\n buzz (1)\n",
+ facets.getAllChildren("b").toString());
+
ExecutorService exec =
new ThreadPoolExecutor(
1,
@@ -517,7 +554,7 @@ public class TestSortedSetDocValuesFacets extends FacetTestCase {
facets = new ConcurrentSortedSetDocValuesFacetCounts(state, exec);
assertEquals(
- "dim=a path=[] value=1 childCount=1\n bar (1)\n",
+ "dim=a path=[] value=3 childCount=3\n bar (1)\n baz (1)\n buz (1)\n",
facets.getTopChildren(10, "a").toString());
assertEquals(
"dim=b path=[buzz] value=1 childCount=1\n baz (1)\n",
@@ -576,6 +613,9 @@ public class TestSortedSetDocValuesFacets extends FacetTestCase {
assertEquals(
"dim=a path=[] value=3 childCount=2\n foo (2)\n baz (1)\n",
facets.getTopChildren(10, "a").toString());
+ assertEquals(
+ "dim=a path=[] value=3 childCount=2\n baz (1)\n foo (2)\n",
+ facets.getAllChildren("a").toString());
assertEquals(
"dim=b path=[] value=1 childCount=1\n bar (1)\n",
facets.getTopChildren(10, "b").toString());
@@ -602,7 +642,10 @@ public class TestSortedSetDocValuesFacets extends FacetTestCase {
doc.add(new SortedSetDocValuesFacetField("c", "buzz", "bar"));
writer.addDocument(config.build(doc));
doc = new Document();
- doc.add(new SortedSetDocValuesFacetField("c", "buzz", "baz"));
+ doc.add(new SortedSetDocValuesFacetField("c", "buzz", "buz"));
+ writer.addDocument(config.build(doc));
+ doc = new Document();
+ doc.add(new SortedSetDocValuesFacetField("c", "buz", "baz"));
writer.addDocument(config.build(doc));
if (random().nextBoolean()) {
writer.commit();
@@ -625,7 +668,10 @@ public class TestSortedSetDocValuesFacets extends FacetTestCase {
Facets facets = getAllFacets(searcher, state, exec);
assertEquals(
- "dim=c path=[buzz] value=2 childCount=2\n bar (1)\n baz (1)\n",
+ "dim=c path=[buzz] value=2 childCount=2\n bar (1)\n buz (1)\n",
+ facets.getTopChildren(10, "c", "buzz").toString());
+ assertEquals(
+ "dim=c path=[buzz] value=2 childCount=2\n bar (1)\n buz (1)\n",
facets.getTopChildren(10, "c", "buzz").toString());
DrillDownQuery q = new DrillDownQuery(config);
@@ -999,6 +1045,20 @@ public class TestSortedSetDocValuesFacets extends FacetTestCase {
"dim=d path=[] value=2 childCount=2\n biz1 (1)\n biz2 (1)\n",
topDimsResults2.get(2).toString());
+ // test getAllChildren
+ assertEquals(
+ "dim=a path=[] value=3 childCount=3\n foo1 (1)\n foo2 (1)\n foo3 (1)\n",
+ facets.getAllChildren("a").toString());
+ assertEquals(
+ "dim=b path=[] value=2 childCount=2\n bar1 (1)\n bar2 (1)\n",
+ facets.getAllChildren("b").toString());
+ assertEquals(
+ "dim=c path=[] value=1 childCount=1\n baz1 (1)\n",
+ facets.getAllChildren("c").toString());
+ assertEquals(
+ "dim=d path=[] value=2 childCount=2\n biz1 (1)\n biz2 (1)\n",
+ facets.getAllChildren("d").toString());
+
Collection<Accountable> resources = state.getChildResources();
assertTrue(state.toString().contains(FacetsConfig.DEFAULT_INDEX_FIELD_NAME));
if (searcher.getIndexReader().leaves().size() > 1) {
@@ -1071,6 +1131,14 @@ public class TestSortedSetDocValuesFacets extends FacetTestCase {
assertEquals(
"dim=d path=[] value=2 childCount=1\n foo (2)\n", results.get(0).toString());
+ // test getAllChildren
+ assertEquals(
+ "dim=d path=[foo] value=2 childCount=2\n bar (1)\n baz (1)\n",
+ facets.getAllChildren("d", "foo").toString());
+ assertEquals(
+ "dim=d path=[] value=2 childCount=1\n foo (2)\n",
+ facets.getAllChildren("d").toString());
+
Collection<Accountable> resources = state.getChildResources();
assertTrue(state.toString().contains(FacetsConfig.DEFAULT_INDEX_FIELD_NAME));
if (searcher.getIndexReader().leaves().size() > 1) {
@@ -1124,6 +1192,9 @@ public class TestSortedSetDocValuesFacets extends FacetTestCase {
assertEquals(
"dim=a path=[] 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.getAllChildren("a").toString());
} finally {
if (exec != null) exec.shutdownNow();
}
@@ -1137,10 +1208,12 @@ public class TestSortedSetDocValuesFacets extends FacetTestCase {
FacetsConfig config = new FacetsConfig();
config.setHierarchical("b", true);
+ config.setMultiValued("b", true);
Document doc = new Document();
doc.add(new SortedSetDocValuesFacetField("a", "foo1"));
doc.add(new SortedSetDocValuesFacetField("b", "foo", "bar"));
+ doc.add(new SortedSetDocValuesFacetField("b", "boo", "buzzz"));
writer.addDocument(config.build(doc));
writer.commit();
@@ -1171,8 +1244,11 @@ public class TestSortedSetDocValuesFacets extends FacetTestCase {
"dim=a path=[] value=2 childCount=2\n foo1 (1)\n foo2 (1)\n",
facets.getTopChildren(10, "a").toString());
assertEquals(
- "dim=b path=[] value=2 childCount=1\n foo (2)\n",
+ "dim=b path=[] value=2 childCount=2\n foo (2)\n boo (1)\n",
facets.getTopChildren(10, "b").toString());
+ assertEquals(
+ "dim=b path=[] value=2 childCount=2\n boo (1)\n foo (2)\n",
+ facets.getAllChildren("b").toString());
assertEquals(
"dim=b path=[foo] value=2 childCount=2\n bar (1)\n buzz (1)\n",
facets.getTopChildren(10, "b", "foo").toString());
@@ -1525,6 +1601,38 @@ public class TestSortedSetDocValuesFacets extends FacetTestCase {
FacetResult actualResult = facets.getTopChildren(10, dimResult.dim, currPath);
try {
assertEquals(expectedResult, actualResult);
+ // test getAllChildren
+ FacetResult allChildrenResult =
+ facets.getAllChildren(dimResult.dim, currPath);
+ if (expectedResult != null && allChildrenResult != null) {
+ // sort actual allChildrenResult labels by value, count (since
+ // we have no insight into the ordinals assigned to the values, we resort)
+ Arrays.sort(
+ allChildrenResult.labelValues,
+ (a, b) -> {
+ int cmp = a.label.compareTo(b.label); // low-to-high
+ if (cmp == 0) {
+ cmp =
+ Long.compare(
+ b.value.longValue(), a.value.longValue()); // low-to-high
+ }
+ return cmp;
+ });
+ // also sort expected labels by value to match the sorting behavior of
+ // getAllChildren
+ Arrays.sort(
+ expectedResult.labelValues,
+ (a, b) -> {
+ int cmp = a.label.compareTo(b.label); // low-to-high
+ if (cmp == 0) {
+ cmp =
+ Long.compare(
+ b.value.longValue(), a.value.longValue()); // low-to-high
+ }
+ return cmp;
+ });
+ assertEquals(expectedResult, allChildrenResult);
+ }
} catch (AssertionError e) {
System.out.println(iter);
System.out.println(config.getDimConfig(dimResult.dim).hierarchical);
@@ -1600,6 +1708,8 @@ public class TestSortedSetDocValuesFacets extends FacetTestCase {
// make sure the result is null (and no exception was thrown)
assertNull(result);
+ result = facets.getAllChildren("non-existent dimension");
+ assertNull(result);
} finally {
if (exec != null) exec.shutdownNow();
}
@@ -1632,6 +1742,8 @@ public class TestSortedSetDocValuesFacets extends FacetTestCase {
// make sure the result is null (and no exception was thrown)
assertNull(result);
+ result = facets.getAllChildren("non-existent dimension");
+ assertNull(result);
expectThrows(
IllegalArgumentException.class,
@@ -1669,6 +1781,8 @@ public class TestSortedSetDocValuesFacets extends FacetTestCase {
// make sure the result is null (and no exception was thrown)
assertNull(result);
+ result = facets.getAllChildren("fizz", "fake", "path");
+ assertNull(result);
} finally {
if (exec != null) exec.shutdownNow();
}
diff --git a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyFacetAssociations.java b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyFacetAssociations.java
index ab4f02639f6..2b56ba02891 100644
--- a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyFacetAssociations.java
+++ b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyFacetAssociations.java
@@ -18,6 +18,8 @@ package org.apache.lucene.facet.taxonomy;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -29,6 +31,7 @@ import org.apache.lucene.facet.Facets;
import org.apache.lucene.facet.FacetsCollector;
import org.apache.lucene.facet.FacetsCollectorManager;
import org.apache.lucene.facet.FacetsConfig;
+import org.apache.lucene.facet.LabelAndValue;
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyReader;
import org.apache.lucene.facet.taxonomy.directory.DirectoryTaxonomyWriter;
import org.apache.lucene.index.BinaryDocValues;
@@ -198,6 +201,9 @@ public class TestTaxonomyFacetAssociations extends FacetTestCase {
assertEquals(
"dim=int path=[] 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",
+ sortAllChildren(facets.getAllChildren("int")).toString());
assertEquals(
"Wrong count for category 'a'!", 200, facets.getSpecificValue("int", "a").intValue());
assertEquals(
@@ -270,6 +276,9 @@ public class TestTaxonomyFacetAssociations extends FacetTestCase {
assertEquals(
"dim=float path=[] 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",
+ sortAllChildren(facets.getAllChildren("float")).toString());
assertEquals(
"Wrong count for category 'a'!",
50f,
@@ -388,6 +397,12 @@ public class TestTaxonomyFacetAssociations extends FacetTestCase {
() -> {
facets.getTopChildren(10, "float");
});
+
+ expectThrows(
+ IllegalArgumentException.class,
+ () -> {
+ facets.getAllChildren("float");
+ });
}
public void testMixedTypesInSameIndexField() throws Exception {
@@ -464,6 +479,11 @@ public class TestTaxonomyFacetAssociations extends FacetTestCase {
assertEquals(
"dim=int path=[] value=-1 childCount=2\n b (150)\n a (100)\n",
facets.getTopChildren(10, "int").toString());
+
+ assertEquals(
+ "dim=int path=[] value=-1 childCount=2\n a (100)\n b (150)\n",
+ sortAllChildren(facets.getAllChildren("int")).toString());
+
assertEquals(
"Wrong count for category 'a'!", 100, facets.getSpecificValue("int", "a").intValue());
assertEquals(
@@ -489,15 +509,20 @@ public class TestTaxonomyFacetAssociations extends FacetTestCase {
}
FacetResult facetResult = facets.getTopChildren(10, dim);
+ FacetResult allChildrenResult = facets.getAllChildren(dim);
if (expected.isEmpty()) {
// If we hit the rare random case where nothing is indexed for the dim, we expect a null
// facetResult (see: LUCENE-10529)
assertNull(facetResult);
+ assertNull(allChildrenResult);
} else {
assertEquals(dim, facetResult.dim);
+ assertEquals(dim, allChildrenResult.dim);
assertEquals(aggregatedValue, facetResult.value.intValue());
+ assertEquals(aggregatedValue, allChildrenResult.value.intValue());
assertEquals(expected.size(), facetResult.childCount);
+ assertEquals(expected.size(), allChildrenResult.childCount);
}
}
@@ -523,15 +548,31 @@ public class TestTaxonomyFacetAssociations extends FacetTestCase {
}
FacetResult facetResult = facets.getTopChildren(10, dim);
+ FacetResult allChildrenResult = facets.getAllChildren(dim);
if (expected.isEmpty()) {
// If we hit the rare random case where nothing is indexed for the dim, we expect a null
// facetResult (see: LUCENE-10529)
assertNull(facetResult);
+ assertNull(allChildrenResult);
} else {
assertEquals(dim, facetResult.dim);
+ assertEquals(dim, allChildrenResult.dim);
assertEquals(aggregatedValue, facetResult.value.floatValue(), 1f);
+ assertEquals(aggregatedValue, allChildrenResult.value.floatValue(), 1f);
assertEquals(expected.size(), facetResult.childCount);
+ assertEquals(expected.size(), allChildrenResult.childCount);
}
}
+
+ // since we have no insight into the ordinals assigned to the values, we sort labels by value and
+ // count in
+ // ascending order in order to compare with expected results
+ private static FacetResult sortAllChildren(FacetResult allChildrenResult) {
+ Arrays.sort(
+ allChildrenResult.labelValues,
+ Comparator.comparing((LabelAndValue a) -> a.label)
+ .thenComparingLong(a -> a.value.longValue()));
+ return allChildrenResult;
+ }
}
diff --git a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyFacetCounts.java b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyFacetCounts.java
index 7ef2103ae56..f5ff3b78648 100644
--- a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyFacetCounts.java
+++ b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyFacetCounts.java
@@ -20,7 +20,9 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -128,6 +130,14 @@ public class TestTaxonomyFacetCounts extends FacetTestCase {
"dim=Author path=[] value=5 childCount=4\n Lisa (2)\n Bob (1)\n Susan (1)\n Frank (1)\n",
facets.getTopChildren(10, "Author").toString());
+ // test getAllChildren
+ assertEquals(
+ "dim=Publish Date path=[] value=5 childCount=3\n 1999 (1)\n 2010 (2)\n 2012 (2)\n",
+ sortAllChildren(facets.getAllChildren("Publish Date")).toString());
+ assertEquals(
+ "dim=Author path=[] value=5 childCount=4\n Bob (1)\n Frank (1)\n Lisa (2)\n Susan (1)\n",
+ sortAllChildren(facets.getAllChildren("Author")).toString());
+
// test getAllDims
List<FacetResult> results = facets.getAllDims(10);
// test getTopDims(10, 10) and expect same results from getAllDims(10)
@@ -312,6 +322,11 @@ public class TestTaxonomyFacetCounts extends FacetTestCase {
() -> {
facets.getTopChildren(10, "a");
});
+ expectThrows(
+ IllegalArgumentException.class,
+ () -> {
+ facets.getAllChildren("a");
+ });
writer.close();
IOUtils.close(taxoWriter, searcher.getIndexReader(), taxoReader, taxoDir, dir);
@@ -344,6 +359,12 @@ public class TestTaxonomyFacetCounts extends FacetTestCase {
// make sure the result is null (and no exception was thrown)
assertNull(result);
+ // get facets for the dimension, which was never configured or indexed before
+ FacetResult allChildrenResult = facets.getAllChildren("non-existent dimension");
+
+ // make sure the result is null (and no exception was thrown)
+ assertNull(allChildrenResult);
+
writer.close();
IOUtils.close(taxoWriter, searcher.getIndexReader(), taxoReader, taxoDir, dir);
}
@@ -410,6 +431,10 @@ public class TestTaxonomyFacetCounts extends FacetTestCase {
assertEquals(1, result.labelValues.length);
assertEquals(1, result.labelValues[0].value.intValue());
+ FacetResult allChildren = facets.getAllChildren("a");
+ assertEquals(1, allChildren.labelValues.length);
+ assertEquals(1, allChildren.labelValues[0].value.intValue());
+
writer.close();
IOUtils.close(taxoWriter, searcher.getIndexReader(), taxoReader, dir, taxoDir);
}
@@ -450,6 +475,9 @@ public class TestTaxonomyFacetCounts extends FacetTestCase {
assertEquals(
"dim=dim path=[] value=-1 childCount=2\n test\u001Fone (1)\n test\u001Etwo (1)\n",
result.toString());
+ assertEquals(
+ "dim=dim path=[] value=-1 childCount=2\n test\u001Etwo (1)\n test\u001Fone (1)\n",
+ sortAllChildren(facets.getAllChildren("dim")).toString());
writer.close();
IOUtils.close(taxoWriter, searcher.getIndexReader(), taxoReader, dir, taxoDir);
}
@@ -489,8 +517,11 @@ public class TestTaxonomyFacetCounts extends FacetTestCase {
getAllFacets(FacetsConfig.DEFAULT_INDEX_FIELD_NAME, searcher, taxoReader, config);
assertEquals(1, facets.getTopChildren(10, "dim").value);
+ assertEquals(1, facets.getAllChildren("dim").value);
assertEquals(1, facets.getTopChildren(10, "dim2").value);
+ assertEquals(1, facets.getAllChildren("dim2").value);
assertEquals(1, facets.getTopChildren(10, "dim3").value);
+ assertEquals(1, facets.getAllChildren("dim3").value);
expectThrows(
IllegalArgumentException.class,
() -> {
@@ -549,6 +580,15 @@ public class TestTaxonomyFacetCounts extends FacetTestCase {
}
assertEquals(numLabels, allLabels.size());
+ FacetResult allChildrenResult = facets.getAllChildren("dim");
+ assertEquals(numLabels, result.labelValues.length);
+ Set<String> allChildrenLabels = new HashSet<>();
+ for (LabelAndValue labelValue : allChildrenResult.labelValues) {
+ allChildrenLabels.add(labelValue.label);
+ assertEquals(1, labelValue.value.intValue());
+ }
+ assertEquals(numLabels, allChildrenLabels.size());
+
writer.close();
IOUtils.close(searcher.getIndexReader(), taxoWriter, taxoReader, dir, taxoDir);
}
@@ -625,7 +665,9 @@ public class TestTaxonomyFacetCounts extends FacetTestCase {
Facets facets1 = getTaxonomyFacetCounts(taxoReader, config, sfc);
Facets facets2 = getTaxonomyFacetCounts(taxoReader, config, sfc, "$b");
assertEquals(r.maxDoc(), facets1.getTopChildren(10, "a").value.intValue());
+ assertEquals(r.maxDoc(), facets1.getAllChildren("a").value.intValue());
assertEquals(r.maxDoc(), facets2.getTopChildren(10, "b").value.intValue());
+ assertEquals(r.maxDoc(), facets2.getAllChildren("b").value.intValue());
iw.close();
IOUtils.close(taxoWriter, taxoReader, taxoDir, r, indexDir);
}
@@ -744,6 +786,7 @@ public class TestTaxonomyFacetCounts extends FacetTestCase {
getAllFacets(FacetsConfig.DEFAULT_INDEX_FIELD_NAME, newSearcher(r), taxoReader, config);
assertEquals(10, facets.getTopChildren(2, "a").childCount);
+ assertEquals(10, facets.getAllChildren("a").childCount);
iw.close();
IOUtils.close(taxoWriter, taxoReader, taxoDir, r, indexDir);
@@ -783,6 +826,9 @@ public class TestTaxonomyFacetCounts extends FacetTestCase {
assertEquals(
"dim=Author path=[] value=2 childCount=2\n Bob (1)\n Lisa (1)",
facets.getTopChildren(10, "Author").toString().trim());
+ assertEquals(
+ "dim=Author path=[] value=2 childCount=2\n Bob (1)\n Lisa (1)",
+ sortAllChildren(facets.getAllChildren("Author")).toString().trim());
// -- delete to trigger liveDocs != null
writer.deleteDocuments(new Term("id", "0"));
@@ -794,6 +840,9 @@ public class TestTaxonomyFacetCounts extends FacetTestCase {
assertEquals(
"dim=Author path=[] value=1 childCount=1\n Lisa (1)",
facets.getTopChildren(10, "Author").toString().trim());
+ assertEquals(
+ "dim=Author path=[] value=1 childCount=1\n Lisa (1)",
+ facets.getAllChildren("Author").toString().trim());
IOUtils.close(
writer,
@@ -837,6 +886,9 @@ public class TestTaxonomyFacetCounts extends FacetTestCase {
assertEquals(
"dim=Author path=[] value=2 childCount=2\n Bob (1)\n Lisa (1)",
facets.getTopChildren(10, "Author").toString().trim());
+ assertEquals(
+ "dim=Author path=[] value=2 childCount=2\n Bob (1)\n Lisa (1)",
+ sortAllChildren(facets.getAllChildren("Author")).toString().trim());
// -- delete to trigger liveDocs != null
writer.deleteDocuments(new Term("id", "0"));
@@ -848,6 +900,9 @@ public class TestTaxonomyFacetCounts extends FacetTestCase {
assertEquals(
"dim=Author path=[] value=1 childCount=1\n Lisa (1)",
facets.getTopChildren(10, "Author").toString().trim());
+ assertEquals(
+ "dim=Author path=[] value=1 childCount=1\n Lisa (1)",
+ facets.getAllChildren("Author").toString().trim());
IOUtils.close(
writer,
@@ -914,6 +969,11 @@ public class TestTaxonomyFacetCounts extends FacetTestCase {
for (LabelAndValue labelValue : result.labelValues) {
assertEquals("wrong weight for child " + labelValue.label, 2, labelValue.value.intValue());
}
+ FacetResult allChildrenResult = facets.getAllChildren("A");
+ assertEquals("wrong number of children", 2, allChildrenResult.labelValues.length);
+ for (LabelAndValue labelValue : allChildrenResult.labelValues) {
+ assertEquals("wrong weight for child " + labelValue.label, 2, labelValue.value.intValue());
+ }
IOUtils.close(indexReader, taxoReader, indexDir, taxoDir);
}
@@ -1083,4 +1143,15 @@ public class TestTaxonomyFacetCounts extends FacetTestCase {
indexFieldName, searcher.getIndexReader(), taxoReader, config);
}
}
+
+ // since we have no insight into the ordinals assigned to the values, we sort labels by value and
+ // count in
+ // ascending order in order to compare with expected results
+ private static FacetResult sortAllChildren(FacetResult allChildrenResult) {
+ Arrays.sort(
+ allChildrenResult.labelValues,
+ Comparator.comparing((LabelAndValue a) -> a.label)
+ .thenComparingLong(a -> a.value.longValue()));
+ return allChildrenResult;
+ }
}