This is an automated email from the ASF dual-hosted git repository. dsmiley pushed a commit to branch branch_9x in repository https://gitbox.apache.org/repos/asf/solr.git
commit cfbaf00511337b3c4789486b4e0437cfa51efcfa Author: David Smiley <[email protected]> AuthorDate: Wed Jul 8 13:15:09 2026 -0400 SOLR-17170: Support block/nested docs with index sorting (#4619) (cherry picked from commit 595f760b3b56ae17f231e1b0ad1f4b24f8cdd47e) --- .../unreleased/SOLR-17170-indexSortBlocks.yml | 8 +++++++ .../java/org/apache/solr/schema/IndexSchema.java | 1 + .../org/apache/solr/update/SolrIndexConfig.java | 10 ++++++++ .../org/apache/solr/cloud/TestSegmentSorting.java | 27 ++++++++++++++++++++++ .../apache/solr/update/SolrIndexConfigTest.java | 6 +++++ 5 files changed, 52 insertions(+) diff --git a/changelog/unreleased/SOLR-17170-indexSortBlocks.yml b/changelog/unreleased/SOLR-17170-indexSortBlocks.yml new file mode 100644 index 00000000000..5f9be49f36f --- /dev/null +++ b/changelog/unreleased/SOLR-17170-indexSortBlocks.yml @@ -0,0 +1,8 @@ +title: > + Support block / nested-docs with index sorting +type: added +authors: + - name: David Smiley +links: + - name: SOLR-17170 + url: https://issues.apache.org/jira/browse/SOLR-17170 diff --git a/solr/core/src/java/org/apache/solr/schema/IndexSchema.java b/solr/core/src/java/org/apache/solr/schema/IndexSchema.java index a20c17867b1..9b1a58be7f1 100644 --- a/solr/core/src/java/org/apache/solr/schema/IndexSchema.java +++ b/solr/core/src/java/org/apache/solr/schema/IndexSchema.java @@ -107,6 +107,7 @@ public class IndexSchema { public static final String NEST_PARENT_FIELD_NAME = "_nest_parent_"; public static final String NEST_PATH_FIELD_NAME = "_nest_path_"; public static final String NESTED_VECTORS_PSEUDO_FIELD_NAME = "_nested_vectors_"; + public static final String IS_ROOT_FIELD_NAME = "_is_root_"; public static final String REQUIRED = "required"; public static final String SCHEMA = "schema"; public static final String SIMILARITY = "similarity"; diff --git a/solr/core/src/java/org/apache/solr/update/SolrIndexConfig.java b/solr/core/src/java/org/apache/solr/update/SolrIndexConfig.java index 94c5e63aa37..70b01aa0679 100644 --- a/solr/core/src/java/org/apache/solr/update/SolrIndexConfig.java +++ b/solr/core/src/java/org/apache/solr/update/SolrIndexConfig.java @@ -31,6 +31,7 @@ import org.apache.lucene.index.MergePolicy; import org.apache.lucene.index.MergeScheduler; import org.apache.lucene.search.Sort; import org.apache.lucene.util.InfoStream; +import org.apache.lucene.util.Version; import org.apache.solr.common.ConfigNode; import org.apache.solr.common.MapSerializable; import org.apache.solr.common.util.NamedList; @@ -270,6 +271,15 @@ public class SolrIndexConfig implements MapSerializable { iwc.setIndexSort(indexSort); } + if (iwc.getIndexSort() != null + && schema.isUsableForChildDocs() + && core.getSolrConfig().luceneMatchVersion.onOrAfter(Version.LUCENE_9_12_3)) { + // Lucene 9.12.3 is when this branch gained parent-field support; earlier + // luceneMatchVersion settings didn't set it. This version check allows an upgrading + // user to continue to do index sorting. + iwc.setParentField(IndexSchema.IS_ROOT_FIELD_NAME); + } + iwc.setUseCompoundFile(useCompoundFile); if (mergedSegmentWarmerInfo != null) { diff --git a/solr/core/src/test/org/apache/solr/cloud/TestSegmentSorting.java b/solr/core/src/test/org/apache/solr/cloud/TestSegmentSorting.java index 5a4b24c897a..c79ca7b98d9 100644 --- a/solr/core/src/test/org/apache/solr/cloud/TestSegmentSorting.java +++ b/solr/core/src/test/org/apache/solr/cloud/TestSegmentSorting.java @@ -97,6 +97,33 @@ public class TestSegmentSorting extends SolrCloudTestCase { // add some documents, then optimize to get merged-sorted segments tstes.addDocuments(collectionName, cloudSolrClient, 10, 10, true); + // add block docs with children having different sort values than parent; + // Lucene sorts by parent values only, so block integrity must be preserved + for (int i = 0; i < 5; i++) { + int parentTs = random().nextInt(60); + int childTs = random().nextInt(60); + cloudSolrClient.add( + collectionName, + sdoc( + "id", + 10000 + i, + "timestamp_i_dvo", + parentTs, + "children", + sdocs(sdoc("id", 10100 + i, "timestamp_i_dvo", childTs)))); + } + cloudSolrClient.commit(collectionName); + cloudSolrClient.optimize(collectionName); + // verify block integrity: each child still belongs to its parent after merge-sorting + for (int i = 0; i < 5; i++) { + assertEquals( + 2, + cloudSolrClient + .query(collectionName, params("q", "_root_:" + (10000 + i))) + .getResults() + .getNumFound()); + } + // CommonParams.SEGMENT_TERMINATE_EARLY parameter intentionally absent tstes.queryTimestampDescending(collectionName, cloudSolrClient); diff --git a/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java b/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java index 072835c596e..2ac975e7bb7 100644 --- a/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java +++ b/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java @@ -123,6 +123,7 @@ public class SolrIndexConfigTest extends SolrTestCaseJ4 { assertEquals("ms.maxMergeCount", 987, ms.getMaxMergeCount()); assertEquals("ms.maxThreadCount", 42, ms.getMaxThreadCount()); assertTrue("ms.isAutoIOThrottle", ms.getAutoIOThrottle()); + assertNull("parentField should not be set without index sort", iwc.getParentField()); } @Test @@ -174,6 +175,11 @@ public class SolrIndexConfigTest extends SolrTestCaseJ4 { } final Sort actual = sortingMergePolicy.getSort(); assertEquals("SortingMergePolicy.getSort", expected, actual); + assertEquals("indexSort on IWC", expected, iwc.getIndexSort()); + assertEquals( + "parentField should be set when indexSort is configured", + IndexSchema.IS_ROOT_FIELD_NAME, + iwc.getParentField()); } public void testMergeOnFlushMPSolrIndexConfigCreation() throws Exception {
