This is an automated email from the ASF dual-hosted git repository.

dsmiley pushed a commit to branch branch_10x
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/branch_10x by this push:
     new 54099888e1d SOLR-17170: Support block/nested docs with index sorting 
(#4619)
54099888e1d is described below

commit 54099888e1decb78486ba7dd46c034fa6ef7368e
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    |  9 ++++++++
 .../org/apache/solr/cloud/TestSegmentSorting.java  | 27 ++++++++++++++++++++++
 .../apache/solr/update/SolrIndexConfigTest.java    |  6 +++++
 .../pages/major-changes-in-solr-10.adoc            |  6 +++++
 6 files changed, 57 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 d90251d8635..9710876c045 100644
--- a/solr/core/src/java/org/apache/solr/schema/IndexSchema.java
+++ b/solr/core/src/java/org/apache/solr/schema/IndexSchema.java
@@ -104,6 +104,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 8c672962846..b35a9b3651f 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.MapWriter;
 import org.apache.solr.common.util.NamedList;
@@ -261,6 +262,14 @@ public class SolrIndexConfig implements MapWriter {
       iwc.setIndexSort(indexSort);
     }
 
+    if (iwc.getIndexSort() != null
+        && schema.isUsableForChildDocs()
+        && 
core.getSolrConfig().luceneMatchVersion.onOrAfter(Version.LUCENE_10_4_0)) {
+      // Solr 10 shipped with Lucene 10.3.x, and Solr <=10 didn't set the 
parent field.
+      // 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 bc863239672..3ea8a91919a 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestSegmentSorting.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestSegmentSorting.java
@@ -94,6 +94,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 2b94e57434f..e207d213af0 100644
--- a/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java
+++ b/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java
@@ -113,6 +113,7 @@ public class SolrIndexConfigTest extends SolrTestCaseJ4 {
     assertEquals("ms.maxMergeCount", 987, ms.getMaxMergeCount());
     assertEquals("ms.maxThreadCount", 42, ms.getMaxThreadCount());
     assertFalse("ms.isAutoIOThrottle", ms.getAutoIOThrottle());
+    assertNull("parentField should not be set without index sort", 
iwc.getParentField());
   }
 
   @Test
@@ -163,6 +164,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 {
diff --git 
a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc 
b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
index b374913e64b..2b57a88b16a 100644
--- 
a/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
+++ 
b/solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc
@@ -36,10 +36,16 @@ Solr 10.0 requires at least Java 21, while SolrJ 10.0 
requires at least Java 17.
 
 == Solr 10.1
 
+=== Misc
+
 For SSL (https), it's no longer necessary to set the "urlScheme" cluster 
property since the `SOLR_SSL_ENABLED` env var (or `solr.ssl.enabled` sys-prop) 
suffices.
 These are now honored by CloudSolrClient, as well as scheme detection from the 
connection string / hosts.
 The "urlScheme" cluster property and httpShardHandlerFactory configuration is 
likely to be deprecated; feedback welcome.
 
+If you use 
xref:configuration-guide:index-segments-merging.adoc#customizing-merge-policies[`SortingMergePolicyFactory`]
 for index sorting and your schema declares `\_root_`, Solr configures a new 
mechanism in Lucene that affects the index to support nested/block documents 
with sorted indexes.
+This requires a fresh Solr 10.1 index.
+To retain compatibility with existing sorted indexes, deferring a reindex, 
keep `luceneMatchVersion` at 10.3.1 or earlier in solrconfig.xml.
+
 === Universal connection string support
 
 Introduced a universal Solr connection string for SolrCloud connections.

Reply via email to