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.