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;
+  }
 }