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

commit 7290808902b7fe580ca20f9f0b7cf2a60cc2a455
Author: Jason Gerlowski <[email protected]>
AuthorDate: Fri Aug 28 07:23:30 2026 -0400

    SOLR-18332: Replace CloudSolrStream 'qt' usage (#4816)
    
    The 'qt' parameter and several related methods in SolrJ are deprecated.
    This deprecation may not stick, but it's still worth minimizing use of this
    feature as much as possible.  One place where 'qt' is still used
    frequently is in CloudSolrStream (and related "expression" strings).
    
    This commit addresses this by giving CloudSolrStream and friends a
    constructor parameter that allows users to specify the path at creation-
    time instead of relying on "qt".
    
    CloudSolrStream is also an "Expressible", meaning that it maps to our
    user-facing streaming-expression syntax. So this PR also adds
    "path" as a parameter name in that expression syntax.
    
    (cherry picked from commit 96cf082b6e674dc4dc8322f037901df2d9dacd69)
---
 .../SOLR-18332-streaming-expression-path-param.yml |  13 ++
 .../src/java/org/apache/solr/cli/StreamTool.java   |   2 +-
 .../api/collections/ReindexCollectionCmd.java      |   3 +-
 .../solr/search/join/CrossCollectionJoinQuery.java |   6 +-
 .../org/apache/solr/handler/sql/SolrTable.java     |  17 ++-
 .../modules/query-guide/pages/graph-traversal.adoc |   4 +-
 .../pages/stream-decorator-reference.adoc          | 134 ++++++++++-----------
 .../query-guide/pages/stream-source-reference.adoc |   7 +-
 .../client/solrj/io/graph/GatherNodesStream.java   |   3 +-
 .../client/solrj/io/graph/ShortestPathStream.java  |   3 +-
 .../solr/client/solrj/io/sql/StatementImpl.java    |   5 +-
 .../client/solrj/io/stream/CloudSolrStream.java    |  37 +++++-
 .../solr/client/solrj/io/stream/DrillStream.java   |   4 +-
 .../client/solrj/io/stream/ScoreNodesStream.java   |   4 +-
 .../client/solrj/io/stream/SearchFacadeStream.java |  14 ++-
 .../solr/client/solrj/io/stream/ShuffleStream.java |   8 +-
 .../client/solrj/io/stream/MathExpressionTest.java |   2 +-
 .../solrj/io/stream/StreamDecoratorTest.java       |  58 ++++-----
 .../solrj/io/stream/StreamExpressionTest.java      |  29 ++++-
 .../solr/client/solrj/io/stream/StreamingTest.java |   4 +-
 20 files changed, 205 insertions(+), 152 deletions(-)

diff --git 
a/changelog/unreleased/SOLR-18332-streaming-expression-path-param.yml 
b/changelog/unreleased/SOLR-18332-streaming-expression-path-param.yml
new file mode 100644
index 00000000000..8eaf8a76e28
--- /dev/null
+++ b/changelog/unreleased/SOLR-18332-streaming-expression-path-param.yml
@@ -0,0 +1,13 @@
+# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc
+
+title: >
+  Streaming expressions backed by CloudSolrStream (e.g. 'search', 'shuffle') 
now support a
+  'path' parameter for selecting the request handler to query, as a more 
explicit alternative
+  to embedding a 'qt' parameter.
+type: added
+authors:
+  - name: Jason Gerlowski
+    nick: gerlowskija
+links:
+  - name: SOLR-18332
+    url: https://issues.apache.org/jira/browse/SOLR-18332
diff --git a/solr/core/src/java/org/apache/solr/cli/StreamTool.java 
b/solr/core/src/java/org/apache/solr/cli/StreamTool.java
index 31070e7e27b..22bcd6c6f15 100644
--- a/solr/core/src/java/org/apache/solr/cli/StreamTool.java
+++ b/solr/core/src/java/org/apache/solr/cli/StreamTool.java
@@ -325,7 +325,7 @@ public class StreamTool extends ToolBase {
     String collection = cli.getOptionValue(COLLECTION_OPTION);
 
     return new PushBackStream(
-        new SolrStream(solrUrl + "/solr/" + collection, params("qt", 
"/stream", "expr", expr)));
+        new SolrStream(solrUrl + "/solr", collection, "/stream", 
params("expr", expr)));
   }
 
   private static ModifiableSolrParams params(String... params) {
diff --git 
a/solr/core/src/java/org/apache/solr/cloud/api/collections/ReindexCollectionCmd.java
 
b/solr/core/src/java/org/apache/solr/cloud/api/collections/ReindexCollectionCmd.java
index 822031d4a39..cc1a1ab7078 100644
--- 
a/solr/core/src/java/org/apache/solr/cloud/api/collections/ReindexCollectionCmd.java
+++ 
b/solr/core/src/java/org/apache/solr/cloud/api/collections/ReindexCollectionCmd.java
@@ -413,7 +413,6 @@ public class ReindexCollectionCmd implements 
CollApiCmds.CollectionApiCommand {
       // Recipe taken from:
       // 
http://joelsolr.blogspot.com/2016/10/solr-63-batch-jobs-parallel-etl-and.html
       ModifiableSolrParams q = new ModifiableSolrParams();
-      q.set(CommonParams.QT, "/stream");
       q.set("collection", collection);
       q.set(
           "expr",
@@ -451,7 +450,7 @@ public class ReindexCollectionCmd implements 
CollApiCmds.CollectionApiCommand {
       log.debug("- starting copying documents from {} to {}", collection, 
targetCollection);
       SolrResponse rsp;
       try {
-        rsp = new 
QueryRequest(q).process(ccc.getSolrCloudManager().getSolrClient());
+        rsp = new QueryRequest("/stream", 
q).process(ccc.getSolrCloudManager().getSolrClient());
       } catch (Exception e) {
         throw new SolrException(
             SolrException.ErrorCode.SERVER_ERROR,
diff --git 
a/solr/core/src/java/org/apache/solr/search/join/CrossCollectionJoinQuery.java 
b/solr/core/src/java/org/apache/solr/search/join/CrossCollectionJoinQuery.java
index 6d12f731f11..f1172149262 100644
--- 
a/solr/core/src/java/org/apache/solr/search/join/CrossCollectionJoinQuery.java
+++ 
b/solr/core/src/java/org/apache/solr/search/join/CrossCollectionJoinQuery.java
@@ -241,7 +241,6 @@ public class CrossCollectionJoinQuery extends Query 
implements SolrSearcherRequi
       }
       params.set(CommonParams.FL, fromField);
       params.set(CommonParams.SORT, fromField + " asc");
-      params.set(CommonParams.QT, "/export");
       params.set(CommonParams.WT, CommonParams.JAVABIN);
 
       StreamContext streamContext = new StreamContext();
@@ -263,7 +262,7 @@ public class CrossCollectionJoinQuery extends Query 
implements SolrSearcherRequi
       }
 
       TupleStream cloudSolrStream =
-          new CloudSolrStream(streamingSolrConnection, collection, params);
+          new CloudSolrStream(streamingSolrConnection, collection, "/export", 
params);
       TupleStream uniqueStream = new UniqueStream(cloudSolrStream, new 
FieldEqualitor(fromField));
       uniqueStream.setStreamContext(streamContext);
       return uniqueStream;
@@ -296,10 +295,9 @@ public class CrossCollectionJoinQuery extends Query 
implements SolrSearcherRequi
 
       ModifiableSolrParams params = new ModifiableSolrParams();
       params.set("expr", uniqueExpr.toString());
-      params.set(CommonParams.QT, "/stream");
       params.set(CommonParams.WT, CommonParams.JAVABIN);
 
-      return new SolrStream(solrUrl + "/" + collection, params);
+      return new SolrStream(solrUrl, collection, "/stream", params);
     }
 
     private DocSet getDocSet() throws IOException {
diff --git 
a/solr/modules/sql/src/java/org/apache/solr/handler/sql/SolrTable.java 
b/solr/modules/sql/src/java/org/apache/solr/handler/sql/SolrTable.java
index fde3ef7807a..84180a8f0df 100644
--- a/solr/modules/sql/src/java/org/apache/solr/handler/sql/SolrTable.java
+++ b/solr/modules/sql/src/java/org/apache/solr/handler/sql/SolrTable.java
@@ -369,8 +369,7 @@ class SolrTable extends AbstractQueryableTable implements 
TranslatableTable {
       }
       return limitStream;
     } else {
-      params.add(CommonParams.QT, "/export");
-      return new CloudSolrStream(solrConnection, collection, params);
+      return new CloudSolrStream(solrConnection, collection, "/export", 
params);
     }
   }
 
@@ -546,9 +545,6 @@ class SolrTable extends AbstractQueryableTable implements 
TranslatableTable {
     params.set(CommonParams.FL, fl);
     params.set(CommonParams.Q, query);
     params.set(CommonParams.WT, CommonParams.JAVABIN);
-    // Always use the /export handler for Group By Queries because it requires 
exporting full result
-    // sets.
-    params.set(CommonParams.QT, "/export");
 
     if (numWorkers > 1) {
       params.set("partitionKeys", getPartitionKeys(buckets));
@@ -558,7 +554,9 @@ class SolrTable extends AbstractQueryableTable implements 
TranslatableTable {
 
     TupleStream tupleStream = null;
 
-    CloudSolrStream cstream = new CloudSolrStream(solrConnection, collection, 
params);
+    // Always use the /export handler for Group By Queries because it requires 
exporting full
+    // result sets.
+    CloudSolrStream cstream = new CloudSolrStream(solrConnection, collection, 
"/export", params);
     tupleStream = new RollupStream(cstream, buckets, metrics);
 
     StreamFactory factory =
@@ -805,9 +803,6 @@ class SolrTable extends AbstractQueryableTable implements 
TranslatableTable {
     params.set(CommonParams.FL, fl);
     params.set(CommonParams.Q, query);
     params.set(CommonParams.WT, CommonParams.JAVABIN);
-    // Always use the /export handler for Distinct Queries because it requires 
exporting full result
-    // sets.
-    params.set(CommonParams.QT, "/export");
 
     if (numWorkers > 1) {
       params.set("partitionKeys", getPartitionKeys(buckets));
@@ -817,7 +812,9 @@ class SolrTable extends AbstractQueryableTable implements 
TranslatableTable {
 
     TupleStream tupleStream = null;
 
-    CloudSolrStream cstream = new CloudSolrStream(solrConnection, collection, 
params);
+    // Always use the /export handler for Distinct Queries because it requires 
exporting full
+    // result sets.
+    CloudSolrStream cstream = new CloudSolrStream(solrConnection, collection, 
"/export", params);
     tupleStream = new UniqueStream(cstream, ecomp);
 
     if (numWorkers > 1) {
diff --git a/solr/solr-ref-guide/modules/query-guide/pages/graph-traversal.adoc 
b/solr/solr-ref-guide/modules/query-guide/pages/graph-traversal.adoc
index 1d034f5bfce..3f506648732 100644
--- a/solr/solr-ref-guide/modules/query-guide/pages/graph-traversal.adoc
+++ b/solr/solr-ref-guide/modules/query-guide/pages/graph-traversal.adoc
@@ -310,7 +310,7 @@ The sample code below shows steps 1 and 2 of the 
recommendation:
 [source,plain]
 ----
  nodes(logs,
-       search(logs, q="userID:user1", fl="articleID", sort="articleID asc", 
fq="action:view", qt="/export"),
+       search(logs, q="userID:user1", fl="articleID", sort="articleID asc", 
fq="action:view", path="/export"),
        walk="articleID->articleID",
        gather="userID",
        fq="action:view",
@@ -505,7 +505,7 @@ top(n="5",
           top(n="30",
               sort="count(*) desc",
               nodes(logs,
-                    search(logs, q="userID:user1", fl="articleID", 
sort="articleID asc", fq="action:read", qt="/export"),
+                    search(logs, q="userID:user1", fl="articleID", 
sort="articleID asc", fq="action:read", path="/export"),
                     walk="articleID->articleID",
                     gather="userID",
                     fq="action:read",
diff --git 
a/solr/solr-ref-guide/modules/query-guide/pages/stream-decorator-reference.adoc 
b/solr/solr-ref-guide/modules/query-guide/pages/stream-decorator-reference.adoc
index d9cadb16c49..ca52627a712 100644
--- 
a/solr/solr-ref-guide/modules/query-guide/pages/stream-decorator-reference.adoc
+++ 
b/solr/solr-ref-guide/modules/query-guide/pages/stream-decorator-reference.adoc
@@ -86,7 +86,7 @@ The following examples show different outputs for this source 
tuple:
 [source,text]
 ----
 cartesianProduct(
-  search(collection1, q="*:*", qt="/export", fl="fieldA, fieldB, fieldC", 
sort="fieldA asc"),
+  search(collection1, q="*:*", path="/export", fl="fieldA, fieldB, fieldC", 
sort="fieldA asc"),
   fieldB
 )
 
@@ -107,7 +107,7 @@ cartesianProduct(
 [source,text]
 ----
 cartesianProduct(
-  search(collection1, q="*:*", qt="/export", fl="fieldA, fieldB, fieldC", 
sort="fieldA asc"),
+  search(collection1, q="*:*", path="/export", fl="fieldA, fieldB, fieldC", 
sort="fieldA asc"),
   sequence(3,4,5) as fieldE
 )
 
@@ -136,7 +136,7 @@ cartesianProduct(
 [source,text]
 ----
 cartesianProduct(
-  search(collection1, q="*:*", qt="/export", fl="fieldA, fieldB, fieldC", 
sort="fieldA asc"),
+  search(collection1, q="*:*", path="/export", fl="fieldA, fieldB, fieldC", 
sort="fieldA asc"),
   fieldB,
   productSort="fieldB desc"
 )
@@ -158,7 +158,7 @@ cartesianProduct(
 [source,text]
 ----
 cartesianProduct(
-  search(collection1, q="*:*", qt="/export", fl="fieldA, fieldB, fieldC", 
sort="fieldA asc"),
+  search(collection1, q="*:*", path="/export", fl="fieldA, fieldB, fieldC", 
sort="fieldA asc"),
   sequence(3,4,5) as fieldE,
   productSort="newFieldE desc"
 )
@@ -188,7 +188,7 @@ cartesianProduct(
 [source,text]
 ----
 cartesianProduct(
-  search(collection1, q="*:*", qt="/export", fl="fieldA, fieldB, fieldC", 
sort="fieldA asc"),
+  search(collection1, q="*:*", path="/export", fl="fieldA, fieldB, fieldC", 
sort="fieldA asc"),
   fieldB as newFieldB,
   productSort="fieldB desc"
 )
@@ -212,7 +212,7 @@ cartesianProduct(
 [source,text]
 ----
 cartesianProduct(
-  search(collection1, q="*:*", qt="/export", fl="fieldA, fieldB, fieldC", 
sort="fieldA asc"),
+  search(collection1, q="*:*", path="/export", fl="fieldA, fieldB, fieldC", 
sort="fieldA asc"),
   fieldB,
   fieldC
 )
@@ -254,7 +254,7 @@ cartesianProduct(
 [source,text]
 ----
 cartesianProduct(
-  search(collection1, qt="/export", q="*:*", fl="fieldA, fieldB, fieldC", 
sort="fieldA asc"),
+  search(collection1, path="/export", q="*:*", fl="fieldA, fieldB, fieldC", 
sort="fieldA asc"),
   fieldB,
   fieldC,
   productSort="fieldC asc"
@@ -297,7 +297,7 @@ cartesianProduct(
 [source,text]
 ----
 cartesianProduct(
-  search(collection1, q="*:*", qt="/export", fl="fieldA, fieldB, fieldC", 
sort="fieldA asc"),
+  search(collection1, q="*:*", path="/export", fl="fieldA, fieldB, fieldC", 
sort="fieldA asc"),
   fieldB,
   fieldC,
   productSort="fieldC asc, fieldB desc"
@@ -340,7 +340,7 @@ cartesianProduct(
 [source,text]
 ----
 cartesianProduct(
-  search(collection1, q="*:*", qt="/export", fl="fieldA, fieldB, fieldC", 
sort="fieldA asc"),
+  search(collection1, q="*:*", path="/export", fl="fieldA, fieldB, fieldC", 
sort="fieldA asc"),
   sequence(3,4,5) as fieldE,
   fieldB
 )
@@ -422,7 +422,7 @@ classify(model(modelCollection,
              cacheMillis=5000),
          search(contentCollection,
              q="id:(a b c)",
-             qt="/export",
+             path="/export",
              fl="text_t, id",
              sort="id asc"),
              field="text_t")
@@ -458,7 +458,7 @@ commit(
     update(
         destinationCollection,
         batchSize=5,
-        search(collection1, q="*:*", qt="/export", 
fl="id,a_s,a_i,a_f,s_multi,i_multi", sort="a_f asc, a_i asc")
+        search(collection1, q="*:*", path="/export", 
fl="id,a_s,a_i,a_f,s_multi,i_multi", sort="a_f asc, a_i asc")
     )
 )
 ----
@@ -481,14 +481,14 @@ Can be of the format `on="fieldName"`, 
`on="fieldNameInLeft=fieldNameInRight"`,
 [source,text]
 ----
 complement(
-  search(collection1, q="a_s:(setA || setAB)", qt="/export", fl="id,a_s,a_i", 
sort="a_i asc, a_s asc"),
-  search(collection1, q="a_s:(setB || setAB)", qt="/export", fl="id,a_s,a_i", 
sort="a_i asc"),
+  search(collection1, q="a_s:(setA || setAB)", path="/export", 
fl="id,a_s,a_i", sort="a_i asc, a_s asc"),
+  search(collection1, q="a_s:(setB || setAB)", path="/export", 
fl="id,a_s,a_i", sort="a_i asc"),
   on="a_i"
 )
 
 complement(
-  search(collection1, q="a_s:(setA || setAB)", qt="/export", fl="id,a_s,a_i", 
sort="a_i asc, a_s asc"),
-  search(collection1, q="a_s:(setB || setAB)", qt="/export", fl="id,a_s,a_i", 
sort="a_i asc, a_s asc"),
+  search(collection1, q="a_s:(setA || setAB)", path="/export", 
fl="id,a_s,a_i", sort="a_i asc, a_s asc"),
+  search(collection1, q="a_s:(setB || setAB)", path="/export", 
fl="id,a_s,a_i", sort="a_i asc, a_s asc"),
   on="a_i,a_s"
 )
 ----
@@ -649,7 +649,7 @@ This is similar to the `<<update,update()>>` function 
described below.
         batchSize=500,
         search(collection1,
                q=old_data:true,
-               qt="/export",
+               path="/export",
                fl="id",
                sort="a_f asc, a_i asc"))
 
@@ -779,7 +779,7 @@ Formatted as `on="fieldNameInTuple=fieldNameInCollection"`.
 [source,text]
 ----
 fetch(addresses,
-      search(people, q="*:*", qt="/export", fl="username, firstName, 
lastName", sort="username asc"),
+      search(people, q="*:*", path="/export", fl="username, firstName, 
lastName", sort="username asc"),
       fl="streetAddress, city, state, country, zip",
       on="username=userId")
 ----
@@ -810,21 +810,21 @@ Can be of the format `on="fieldName"`, 
`on="fieldNameInLeft=fieldNameInRight"`,
 [source,text]
 ----
 fullOuterJoin(
-  search(people, q="*:*", qt="/export", fl="personId,name", sort="personId 
asc"),
-  search(pets, q="type:cat", qt="/export", fl="personId,petName", 
sort="personId asc"),
+  search(people, q="*:*", path="/export", fl="personId,name", sort="personId 
asc"),
+  search(pets, q="type:cat", path="/export", fl="personId,petName", 
sort="personId asc"),
   on="personId"
 )
 
 fullOuterJoin(
-  search(people, q="*:*", qt="/export", fl="personId,name", sort="personId 
asc"),
-  search(pets, q="type:cat", qt="/export", fl="ownerId,petName", sort="ownerId 
asc"),
+  search(people, q="*:*", path="/export", fl="personId,name", sort="personId 
asc"),
+  search(pets, q="type:cat", path="/export", fl="ownerId,petName", 
sort="ownerId asc"),
   on="personId=ownerId"
 )
 
 fullOuterJoin(
-  search(people, q="*:*", qt="/export", fl="personId,name", sort="personId 
asc"),
+  search(people, q="*:*", path="/export", fl="personId,name", sort="personId 
asc"),
   select(
-    search(pets, q="type:cat", qt="/export", fl="ownerId,name", sort="ownerId 
asc"),
+    search(pets, q="type:cat", path="/export", fl="ownerId,name", 
sort="ownerId asc"),
     ownerId,
     name as petName
   ),
@@ -920,7 +920,7 @@ having(rollup(over=a_s,
               sum(a_i),
               search(collection1,
                      q="*:*",
-                     qt="/export",
+                     path="/export",
                      fl="id,a_s,a_i,a_f",
                      sort="a_s asc")),
        and(gt(sum(a_i), 100), lt(sum(a_i), 110)))
@@ -955,21 +955,21 @@ Can be of the format `on="fieldName"`, 
`on="fieldNameInLeft=fieldNameInRight"`,
 [source,text]
 ----
 hashJoin(
-  search(people, q="*:*", qt="/export", fl="personId,name", sort="personId 
asc"),
-  hashed=search(pets, q="type:cat", qt="/export", fl="personId,petName", 
sort="personId asc"),
+  search(people, q="*:*", path="/export", fl="personId,name", sort="personId 
asc"),
+  hashed=search(pets, q="type:cat", path="/export", fl="personId,petName", 
sort="personId asc"),
   on="personId"
 )
 
 hashJoin(
   search(people, q="*:*", fl="personId,name", sort="personId asc"),
-  hashed=search(pets, q="type:cat", qt="/export", fl="ownerId,petName", 
sort="ownerId asc"),
+  hashed=search(pets, q="type:cat", path="/export", fl="ownerId,petName", 
sort="ownerId asc"),
   on="personId=ownerId"
 )
 
 hashJoin(
-  search(people, q="*:*", qt="/export", fl="personId,name", sort="personId 
asc"),
+  search(people, q="*:*", path="/export", fl="personId,name", sort="personId 
asc"),
   hashed=select(
-    search(pets, q="type:cat", qt="/export", fl="ownerId,name", sort="ownerId 
asc"),
+    search(pets, q="type:cat", path="/export", fl="ownerId,name", 
sort="ownerId asc"),
     ownerId,
     name as petName
   ),
@@ -999,21 +999,21 @@ Can be of the format `on="fieldName"`, 
`on="fieldNameInLeft=fieldNameInRight"`,
 [source,text]
 ----
 innerJoin(
-  search(people, q="*:*", qt="/export", fl="personId,name", sort="personId 
asc"),
-  search(pets, q="type:cat", qt="/export", fl="personId,petName", 
sort="personId asc"),
+  search(people, q="*:*", path="/export", fl="personId,name", sort="personId 
asc"),
+  search(pets, q="type:cat", path="/export", fl="personId,petName", 
sort="personId asc"),
   on="personId"
 )
 
 innerJoin(
-  search(people, q="*:*", qt="/export", fl="personId,name", sort="personId 
asc"),
-  search(pets, q="type:cat", qt="/export", fl="ownerId,petName", sort="ownerId 
asc"),
+  search(people, q="*:*", path="/export", fl="personId,name", sort="personId 
asc"),
+  search(pets, q="type:cat", path="/export", fl="ownerId,petName", 
sort="ownerId asc"),
   on="personId=ownerId"
 )
 
 innerJoin(
-  search(people, q="*:*", qt="/export", fl="personId,name", sort="personId 
asc"),
+  search(people, q="*:*", path="/export", fl="personId,name", sort="personId 
asc"),
   select(
-    search(pets, q="type:cat", qt="/export", fl="ownerId,name", sort="ownerId 
asc"),
+    search(pets, q="type:cat", path="/export", fl="ownerId,name", 
sort="ownerId asc"),
     ownerId,
     name as petName
   ),
@@ -1040,14 +1040,14 @@ Can be of the format `on="fieldName"`, 
`on="fieldNameInLeft=fieldNameInRight"`,
 [source,text]
 ----
 intersect(
-  search(collection1, q="a_s:(setA || setAB)", qt="/export", fl="id,a_s,a_i", 
sort="a_i asc, a_s asc"),
-  search(collection1, q="a_s:(setB || setAB)", qt="/export", fl="id,a_s,a_i", 
sort="a_i asc"),
+  search(collection1, q="a_s:(setA || setAB)", path="/export", 
fl="id,a_s,a_i", sort="a_i asc, a_s asc"),
+  search(collection1, q="a_s:(setB || setAB)", path="/export", 
fl="id,a_s,a_i", sort="a_i asc"),
   on="a_i"
 )
 
 intersect(
-  search(collection1, q="a_s:(setA || setAB)", qt="/export", fl="id,a_s,a_i", 
sort="a_i asc, a_s asc"),
-  search(collection1, q="a_s:(setB || setAB)", qt="/export", fl="id,a_s,a_i", 
sort="a_i asc, a_s asc"),
+  search(collection1, q="a_s:(setA || setAB)", path="/export", 
fl="id,a_s,a_i", sort="a_i asc, a_s asc"),
+  search(collection1, q="a_s:(setB || setAB)", path="/export", 
fl="id,a_s,a_i", sort="a_i asc, a_s asc"),
   on="a_i,a_s"
 )
 ----
@@ -1076,21 +1076,21 @@ Can be of the format `on="fieldName"`, 
`on="fieldNameInLeft=fieldNameInRight"`,
 [source,text]
 ----
 leftOuterJoin(
-  search(people, q="*:*", qt="/export", fl="personId,name", sort="personId 
asc"),
-  search(pets, q="type:cat", qt="/export", fl="personId,petName", 
sort="personId asc"),
+  search(people, q="*:*", path="/export", fl="personId,name", sort="personId 
asc"),
+  search(pets, q="type:cat", path="/export", fl="personId,petName", 
sort="personId asc"),
   on="personId"
 )
 
 leftOuterJoin(
-  search(people, q="*:*", qt="/export", fl="personId,name", sort="personId 
asc"),
-  search(pets, q="type:cat", qt="/export", fl="ownerId,petName", sort="ownerId 
asc"),
+  search(people, q="*:*", path="/export", fl="personId,name", sort="personId 
asc"),
+  search(pets, q="type:cat", path="/export", fl="ownerId,petName", 
sort="ownerId asc"),
   on="personId=ownerId"
 )
 
 leftOuterJoin(
-  search(people, q="*:*", qt="/export", fl="personId,name", sort="personId 
asc"),
+  search(people, q="*:*", path="/export", fl="personId,name", sort="personId 
asc"),
   select(
-    search(pets, q="type:cat", qt="/export", fl="ownerId,name", sort="ownerId 
asc"),
+    search(pets, q="type:cat", path="/export", fl="ownerId,name", 
sort="ownerId asc"),
     ownerId,
     name as petName
   ),
@@ -1143,12 +1143,12 @@ Multiple fields can be provided in the form `fieldA 
order, fieldB order`.
 merge(
       search(collection1,
              q="id:(0 3 4)",
-             qt="/export",
+             path="/export",
              fl="id,a_s,a_i,a_f",
              sort="a_f asc"),
       search(collection1,
              q="id:(1)",
-             qt="/export",
+             path="/export",
              fl="id,a_s,a_i,a_f",
              sort="a_f asc"),
       on="a_f asc")
@@ -1161,22 +1161,22 @@ merge(
 merge(
       search(collection1,
              q="id:(0 3 4)",
-             qt="/export",
+             path="/export",
              fl="id,fieldA,fieldB,fieldC",
              sort="fieldA asc, fieldB desc"),
       search(collection1,
              q="id:(1)",
-             qt="/export",
+             path="/export",
              fl="id,fieldA",
              sort="fieldA asc"),
       search(collection2,
              q="id:(10 11 13)",
-             qt="/export",
+             path="/export",
              fl="id,fieldA,fieldC",
              sort="fieldA asc"),
       search(collection3,
              q="id:(987)",
-             qt="/export",
+             path="/export",
              fl="id,fieldA,fieldC",
              sort="fieldA asc"),
       on="fieldA asc")
@@ -1206,7 +1206,7 @@ This gives valuable information such as:
 [source,text]
 ----
  parallel(workerCollection,
-          null(search(collection1, q="*:*", fl="id,a_s,a_i,a_f", sort="a_s 
desc", qt="/export", partitionKeys="a_s")),
+          null(search(collection1, q="*:*", fl="id,a_s,a_i,a_f", sort="a_s 
desc", path="/export", partitionKeys="a_s")),
           workers="20",
           zkHost="localhost:9983",
           sort="a_s desc")
@@ -1244,21 +1244,21 @@ Can be of the format `on="fieldName"`, 
`on="fieldNameInLeft=fieldNameInRight"`,
 [source,text]
 ----
 outerHashJoin(
-  search(people, q="*:*", qt="/export", fl="personId,name", sort="personId 
asc"),
-  hashed=search(pets, q="type:cat", qt="/export", fl="personId,petName", 
sort="personId asc"),
+  search(people, q="*:*", path="/export", fl="personId,name", sort="personId 
asc"),
+  hashed=search(pets, q="type:cat", path="/export", fl="personId,petName", 
sort="personId asc"),
   on="personId"
 )
 
 outerHashJoin(
-  search(people, q="*:*", qt="/export", fl="personId,name", sort="personId 
asc"),
-  hashed=search(pets, q="type:cat", qt="/export", fl="ownerId,petName", 
sort="ownerId asc"),
+  search(people, q="*:*", path="/export", fl="personId,name", sort="personId 
asc"),
+  hashed=search(pets, q="type:cat", path="/export", fl="ownerId,petName", 
sort="ownerId asc"),
   on="personId=ownerId"
 )
 
 outerHashJoin(
-  search(people, q="*:*", qt="/export", fl="personId,name", sort="personId 
asc"),
+  search(people, q="*:*", path="/export", fl="personId,name", sort="personId 
asc"),
   hashed=select(
-    search(pets, q="type:cat", qt="/export", fl="ownerId,name", sort="ownerId 
asc"),
+    search(pets, q="type:cat", path="/export", fl="ownerId,name", 
sort="ownerId asc"),
     ownerId,
     name as petName
   ),
@@ -1307,7 +1307,7 @@ Zookeeper Credentials and ACLs will only be included if 
the same ZkHost is used
 [source,text]
 ----
  parallel(workerCollection,
-          rollup(search(collection1, q="*:*", fl="id,year_i,month_i,day_i", 
qt="/export", sort="year_i desc,month_i desc,day_i asc", 
partitionKeys="year_i"),
+          rollup(search(collection1, q="*:*", fl="id,year_i,month_i,day_i", 
path="/export", sort="year_i desc,month_i desc,day_i asc", 
partitionKeys="year_i"),
                  over="year_i", count(*)),
           workers="20",
           zkHost="localhost:9983",
@@ -1425,7 +1425,7 @@ Accordingly, the sort order of the underlying stream must 
be aligned with the gr
 
 [source,text]
 ----
-reduce(search(collection1, q="*:*", qt="/export", fl="id,a_s,a_i,a_f", 
sort="a_s asc, a_f asc"),
+reduce(search(collection1, q="*:*", path="/export", fl="id,a_s,a_i,a_f", 
sort="a_s asc, a_f asc"),
        by="a_s",
        group(sort="a_f desc", n="4")
 )
@@ -1455,7 +1455,7 @@ Currently supported metrics are `sum(col)`, `avg(col)`, 
`min(col)`, `max(col)`,
 [source,text]
 ----
 rollup(
-   search(collection1, q="*:*", qt="/export", fl="a_s,a_i,a_f", qt="/export", 
sort="a_s asc"),
+   search(collection1, q="*:*", path="/export", fl="a_s,a_i,a_f", sort="a_s 
asc"),
    over="a_s",
    sum(a_i),
    sum(a_f),
@@ -1506,7 +1506,7 @@ One can provide a list of operations and evaluators to 
perform on any fields, su
 ----
 // output tuples with fields teamName, wins, losses, and winPercentages where 
a null value for wins or losses is translated to the value of 0
 select(
-  search(collection1, fl="id,teamName_s,wins,losses", q="*:*", qt="/export", 
sort="id asc"),
+  search(collection1, fl="id,teamName_s,wins,losses", q="*:*", path="/export", 
sort="id asc"),
   teamName_s as teamName,
   wins,
   losses,
@@ -1537,8 +1537,8 @@ Notice that it uses an efficient innerJoin by first 
ordering by the person/owner
 ----
 sort(
   innerJoin(
-    search(people, q="*:*", qt="/export", fl="id,name", sort="id asc"),
-    search(pets, q="type:dog", qt="/export", fl="owner,petName", sort="owner 
asc"),
+    search(people, q="*:*", path="/export", fl="id,name", sort="id asc"),
+    search(pets, q="type:dog", path="/export", fl="owner,petName", sort="owner 
asc"),
     on="id=owner"
   ),
   by="name asc, petName asc"
@@ -1568,7 +1568,7 @@ The top function re-orders the results of the underlying 
stream.
 top(n=3,
      search(collection1,
             q="*:*",
-            qt="/export",
+            path="/export",
             fl="id,a_s,a_i,a_f",
             sort="a_f desc, a_i desc"),
       sort="a_f asc, a_i asc")
@@ -1596,7 +1596,7 @@ When executed in the parallel, the `partitionKeys` 
parameter must be the same as
 unique(
   search(collection1,
          q="*:*",
-         qt="/export",
+         path="/export",
          fl="id,a_s,a_i,a_f",
          sort="a_f asc, a_i asc"),
   over="a_f")
@@ -1621,7 +1621,7 @@ The `update` function wraps another functions and sends 
the tuples to a SolrClou
         batchSize=500,
         search(collection1,
                q=*:*,
-               qt="/export",
+               path="/export",
                fl="id,a_s,a_i,a_f,s_multi,i_multi",
                sort="a_f asc, a_i asc"))
 
diff --git 
a/solr/solr-ref-guide/modules/query-guide/pages/stream-source-reference.adoc 
b/solr/solr-ref-guide/modules/query-guide/pages/stream-source-reference.adoc
index c23af69f8b4..61d79b445d2 100644
--- a/solr/solr-ref-guide/modules/query-guide/pages/stream-source-reference.adoc
+++ b/solr/solr-ref-guide/modules/query-guide/pages/stream-source-reference.adoc
@@ -22,7 +22,7 @@
 The `search` function searches a SolrCloud collection and emits a stream of 
tuples that match the query.
 This is very similar to a standard Solr query, and uses many of the same 
parameters.
 
-This expression allows you to specify a request handler using the `qt` 
parameter.
+This expression allows you to specify a request handler using the `path` 
parameter (the previously preferred `qt` is also still accepted).
 By default, the `/select` handler is used.
 The `/select` handler can be used for simple rapid prototyping of expressions.
 For production, however, you will most likely want to use the `/export` 
handler which is designed to `sort` and `export` entire result sets.
@@ -39,9 +39,10 @@ To read more about the `/export` handler requirements review 
the section xref:ex
 When using a zookeeper connection string, zookeeper credentials and ACLs will 
only be included if the same zookeeper host is used as the Solr instance that 
you are connecting to (the `chroot` can be different).
 * `zkHost`: (Deprecated, use `solrConnection`) Only needs to be defined if the 
collection being searched is found in a different zkHost than the local stream 
handler.
 Zookeeper Credentials and ACLs will only be included if the same ZkHost is 
used as the Solr instance that you are connecting to (the `chroot` can be 
different).
-* `qt`: Specifies the query type, or request handler, to use.
+* `path`: Specifies the request handler to use.
 Set this to `/export` to work with large result sets.
 The default is `/select`.
+(The formerly preferred name of this parameter, `qt`, is also still accepted.)
 * `rows`: (Mandatory with the `/select` handler) The rows parameter specifies 
how many rows to return.
 This parameter is only needed with the `/select` handler (which is the 
default) since the `/export` handler always returns all rows.
 * `partitionKeys`: Comma delimited list of keys to partition the search 
results by.
@@ -54,7 +55,7 @@ See the 
xref:stream-decorator-reference.adoc#parallel[parallel] function for det
 ----
 expr=search(collection1,
        solrConnection="localhost:9983",
-       qt="/export",
+       path="/export",
        q="*:*",
        fl="id,a_s,a_i,a_f",
        sort="a_f asc, a_i asc")
diff --git 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/graph/GatherNodesStream.java
 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/graph/GatherNodesStream.java
index 8c00cae342d..94a5d4fd5b9 100644
--- 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/graph/GatherNodesStream.java
+++ 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/graph/GatherNodesStream.java
@@ -540,7 +540,6 @@ public class GatherNodesStream extends TupleStream 
implements Expressible {
 
       ModifiableSolrParams joinSParams = new ModifiableSolrParams(queryParams);
       joinSParams.set("fl", buf.toString());
-      joinSParams.set("qt", "/export");
       joinSParams.set(SORT, gather + " asc," + traverseTo + " asc");
 
       StringBuilder nodeQuery = new StringBuilder();
@@ -566,7 +565,7 @@ public class GatherNodesStream extends TupleStream 
implements Expressible {
       try {
         stream =
             new UniqueStream(
-                new CloudSolrStream(solrConnection, collection, joinSParams),
+                new CloudSolrStream(solrConnection, collection, "/export", 
joinSParams),
                 new MultipleFieldEqualitor(
                     new FieldEqualitor(gather), new 
FieldEqualitor(traverseTo)));
         stream.setStreamContext(streamContext);
diff --git 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/graph/ShortestPathStream.java
 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/graph/ShortestPathStream.java
index 58964a9b621..370fa745612 100644
--- 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/graph/ShortestPathStream.java
+++ 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/graph/ShortestPathStream.java
@@ -463,7 +463,6 @@ public class ShortestPathStream extends TupleStream 
implements Expressible {
       String fl = fromField + "," + toField;
 
       joinParams.set("fl", fl);
-      joinParams.set("qt", "/export");
       joinParams.set(SORT, toField + " asc," + fromField + " asc");
 
       StringBuilder nodeQuery = new StringBuilder();
@@ -479,7 +478,7 @@ public class ShortestPathStream extends TupleStream 
implements Expressible {
       try {
         stream =
             new UniqueStream(
-                new CloudSolrStream(solrConnection, collection, joinParams),
+                new CloudSolrStream(solrConnection, collection, "/export", 
joinParams),
                 new MultipleFieldEqualitor(
                     new FieldEqualitor(toField), new 
FieldEqualitor(fromField)));
         stream.setStreamContext(streamContext);
diff --git 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/sql/StatementImpl.java
 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/sql/StatementImpl.java
index f0ff025eda4..2926962b8e3 100644
--- 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/sql/StatementImpl.java
+++ 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/sql/StatementImpl.java
@@ -31,7 +31,6 @@ import org.apache.solr.client.solrj.io.stream.CloudSolrStream;
 import org.apache.solr.client.solrj.io.stream.SolrStream;
 import org.apache.solr.common.cloud.Replica;
 import org.apache.solr.common.cloud.Slice;
-import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.common.params.ModifiableSolrParams;
 
 class StatementImpl implements Statement {
@@ -89,15 +88,13 @@ class StatementImpl implements Statement {
       Collections.shuffle(shuffler, new Random());
 
       ModifiableSolrParams params = new ModifiableSolrParams();
-      params.set(CommonParams.QT, "/sql");
       params.set("stmt", sql);
       for (String propertyName : 
this.connection.getProperties().stringPropertyNames()) {
         params.set(propertyName, 
this.connection.getProperties().getProperty(propertyName));
       }
 
       Replica rep = shuffler.get(0);
-      String url = rep.getCoreUrl();
-      return new SolrStream(url, params);
+      return new SolrStream(rep.getBaseUrl(), rep.getCoreName(), "/sql", 
params);
     } catch (Exception e) {
       throw new IOException(e);
     }
diff --git 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/CloudSolrStream.java
 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/CloudSolrStream.java
index f61ccba0548..b721788f37f 100644
--- 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/CloudSolrStream.java
+++ 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/CloudSolrStream.java
@@ -69,6 +69,7 @@ public class CloudSolrStream extends TupleStream implements 
Expressible {
 
   protected CloudSolrClient.CloudSolrClientConnection solrConnection;
   protected String collection;
+  protected String path;
   protected SolrParams params;
   protected Map<String, String> fieldMappings;
   protected StreamComparator comp;
@@ -95,11 +96,31 @@ public class CloudSolrStream extends TupleStream implements 
Expressible {
     init(solrConnection, collectionName, params);
   }
 
+  /**
+   * @param solrConnection Zookeeper or HTTPS(s) ensemble connection string
+   * @param collectionName Name of the collection to operate on
+   * @param path the request handler path to query (e.g. "/export"). If not 
provided (i.e. {@code
+   *     null}), the handler is instead resolved from a "qt" param embedded in 
{@code params}, or
+   *     defaults to "/select" if no such param is present.
+   * @param params Map&lt;String, String[]&gt; of parameter/value pairs
+   * @throws IOException Something went wrong
+   */
+  public CloudSolrStream(
+      CloudSolrClient.CloudSolrClientConnection solrConnection,
+      String collectionName,
+      String path,
+      SolrParams params)
+      throws IOException {
+    init(solrConnection, collectionName, params);
+    this.path = path;
+  }
+
   public CloudSolrStream(StreamExpression expression, StreamFactory factory) 
throws IOException {
     // grab all parameters out
     String collectionName = factory.getValueOperand(expression, 0);
     List<StreamExpressionNamedParameter> namedParams = 
factory.getNamedOperands(expression);
     StreamExpressionNamedParameter aliasExpression = 
factory.getNamedOperand(expression, "aliases");
+    StreamExpressionNamedParameter pathExpression = 
factory.getNamedOperand(expression, "path");
 
     // Collection Name
     if (null == collectionName) {
@@ -127,7 +148,7 @@ public class CloudSolrStream extends TupleStream implements 
Expressible {
     }
 
     ModifiableSolrParams mParams =
-        buildSolrParamsExcept(namedParams, Set.of("solrConnection", "zkHost", 
"aliases"));
+        buildSolrParamsExcept(namedParams, Set.of("solrConnection", "zkHost", 
"aliases", "path"));
 
     // Aliases, optional, if provided then need to split
     if (null != aliasExpression
@@ -148,6 +169,11 @@ public class CloudSolrStream extends TupleStream 
implements Expressible {
       }
     }
 
+    // Optional "path" parameter
+    if (null != pathExpression && pathExpression.getParameter() instanceof 
StreamExpressionValue) {
+      this.path = ((StreamExpressionValue) 
pathExpression.getParameter()).getValue();
+    }
+
     var solrConnection = factory.buildSolrConnection(expression, 
collectionName);
 
     init(solrConnection, collectionName, mParams);
@@ -181,6 +207,10 @@ public class CloudSolrStream extends TupleStream 
implements Expressible {
     expression.addParameter(
         new StreamExpressionNamedParameter("solrConnection", 
solrConnection.toString()));
 
+    if (null != path) {
+      expression.addParameter(new StreamExpressionNamedParameter("path", 
path));
+    }
+
     // aliases
     if (null != fieldMappings && 0 != fieldMappings.size()) {
       StringBuilder sb = new StringBuilder();
@@ -380,7 +410,7 @@ public class CloudSolrStream extends TupleStream implements 
Expressible {
             getShards(this.solrConnection, this.collection, 
this.streamContext, mParams);
         if (shards.isEmpty())
           throw new IOException("No shards available from ZooKeeper: " + 
this.solrConnection);
-        streamOfSolrStream = shards.stream().map(s -> new SolrStream(s, 
mParams));
+        streamOfSolrStream = shards.stream().map(s -> new SolrStream(s, path, 
mParams));
       } else {
         // stream of replicas to reuse the same SolrHttpClient per baseUrl
         // avoids re-parsing data we already have in the replicas
@@ -389,7 +419,8 @@ public class CloudSolrStream extends TupleStream implements 
Expressible {
         if (replicas.isEmpty())
           throw new IOException("No replicas available from ZooKeeper: " + 
this.solrConnection);
         streamOfSolrStream =
-            replicas.stream().map(r -> new SolrStream(r.getBaseUrl(), mParams, 
r.getCoreName()));
+            replicas.stream()
+                .map(r -> new SolrStream(r.getBaseUrl(), r.getCoreName(), 
path, mParams));
       }
 
       streamOfSolrStream.forEach(
diff --git 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/DrillStream.java
 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/DrillStream.java
index 2312aa52c44..389d1b001e7 100644
--- 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/DrillStream.java
+++ 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/DrillStream.java
@@ -262,14 +262,14 @@ public class DrillStream extends CloudSolrStream 
implements Expressible {
       final ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
       paramsLoc.set(DISTRIB, "false"); // We are the aggregator.
       paramsLoc.set("expr", pushStream.toString());
-      paramsLoc.set("qt", "/export");
       paramsLoc.set("fl", fl);
       paramsLoc.set("sort", sort);
       paramsLoc.set("q", q);
       getReplicas(this.solrConnection, this.collection, this.streamContext, 
paramsLoc)
           .forEach(
               r -> {
-                SolrStream solrStream = new SolrStream(r.getBaseUrl(), 
paramsLoc, r.getCoreName());
+                SolrStream solrStream =
+                    new SolrStream(r.getBaseUrl(), r.getCoreName(), "/export", 
paramsLoc);
                 solrStream.setStreamContext(streamContext);
                 solrStreams.add(solrStream);
               });
diff --git 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/ScoreNodesStream.java
 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/ScoreNodesStream.java
index 1d3e42231ea..1374513b5d4 100644
--- 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/ScoreNodesStream.java
+++ 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/ScoreNodesStream.java
@@ -37,7 +37,6 @@ import 
org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
 import 
org.apache.solr.client.solrj.io.stream.expr.StreamExpressionNamedParameter;
 import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
 import org.apache.solr.client.solrj.request.QueryRequest;
-import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.params.TermsParams;
 import org.apache.solr.common.util.NamedList;
@@ -222,13 +221,12 @@ public class ScoreNodesStream extends TupleStream 
implements Expressible {
 
     CloudSolrClient client = clientCache.getCloudSolrClient(solrConnection);
     ModifiableSolrParams params = new ModifiableSolrParams();
-    params.add(CommonParams.QT, "/terms");
     params.add(TermsParams.TERMS_FIELD, field);
     params.add(TermsParams.TERMS_STATS, "true");
     params.add(TermsParams.TERMS_LIST, builder.toString());
     params.add(TermsParams.TERMS_LIMIT, Integer.toString(nodes.size()));
 
-    QueryRequest request = new QueryRequest(params);
+    QueryRequest request = new QueryRequest("/terms", params);
 
     try {
       // Get the response from the terms component
diff --git 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/SearchFacadeStream.java
 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/SearchFacadeStream.java
index 2bf2fc61974..0105752409f 100644
--- 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/SearchFacadeStream.java
+++ 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/SearchFacadeStream.java
@@ -27,6 +27,7 @@ import 
org.apache.solr.client.solrj.io.stream.expr.Expressible;
 import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
 import 
org.apache.solr.client.solrj.io.stream.expr.StreamExpressionNamedParameter;
 import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionParameter;
+import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionValue;
 import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
 import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.common.params.ModifiableSolrParams;
@@ -53,6 +54,7 @@ public class SearchFacadeStream extends TupleStream 
implements Expressible {
     }
 
     List<StreamExpressionNamedParameter> namedParams = 
factory.getNamedOperands(expression);
+    StreamExpressionNamedParameter pathExpression = 
factory.getNamedOperand(expression, "path");
 
     // Collection Name
     if (null == collectionName) {
@@ -64,13 +66,21 @@ public class SearchFacadeStream extends TupleStream 
implements Expressible {
     }
 
     ModifiableSolrParams mParams =
-        buildSolrParamsExcept(namedParams, Set.of("zkHost", "solrConnection", 
"aliases"));
+        buildSolrParamsExcept(namedParams, Set.of("zkHost", "solrConnection", 
"aliases", "path"));
 
     var solrConnection = factory.buildSolrConnection(expression, 
collectionName);
 
-    if (mParams.get(CommonParams.QT) != null && 
mParams.get(CommonParams.QT).equals("/export")) {
+    String path = null;
+    if (null != pathExpression && pathExpression.getParameter() instanceof 
StreamExpressionValue) {
+      path = ((StreamExpressionValue) 
pathExpression.getParameter()).getValue();
+    }
+
+    if ("/export".equals(path)
+        || (mParams.get(CommonParams.QT) != null
+            && mParams.get(CommonParams.QT).equals("/export"))) {
       CloudSolrStream cloudSolrStream = new CloudSolrStream();
       cloudSolrStream.init(solrConnection, collectionName, mParams);
+      cloudSolrStream.path = path;
       this.innerStream = cloudSolrStream;
     } else {
 
diff --git 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/ShuffleStream.java
 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/ShuffleStream.java
index eb04029d8d1..43f5c3d0acc 100644
--- 
a/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/ShuffleStream.java
+++ 
b/solr/solrj-streaming/src/java/org/apache/solr/client/solrj/io/stream/ShuffleStream.java
@@ -31,7 +31,6 @@ import 
org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
 import 
org.apache.solr.client.solrj.io.stream.expr.StreamExpressionNamedParameter;
 import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionValue;
 import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
-import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.common.params.ModifiableSolrParams;
 
 /**
@@ -95,6 +94,7 @@ public class ShuffleStream extends CloudSolrStream implements 
Expressible {
     var solrConnection = factory.buildSolrConnection(expression, 
collectionName);
 
     init(solrConnection, collectionName, mParams);
+    this.path = "/export";
   }
 
   @Override
@@ -169,10 +169,4 @@ public class ShuffleStream extends CloudSolrStream 
implements Expressible {
 
     return explanation;
   }
-
-  @Override
-  public ModifiableSolrParams adjustParams(ModifiableSolrParams mParams) {
-    mParams.set(CommonParams.QT, "/export");
-    return mParams;
-  }
 }
diff --git 
a/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/MathExpressionTest.java
 
b/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/MathExpressionTest.java
index 5f19648f936..566e051a0a7 100644
--- 
a/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/MathExpressionTest.java
+++ 
b/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/MathExpressionTest.java
@@ -6239,7 +6239,7 @@ public class MathExpressionTest extends SolrCloudTestCase 
{
             + COLLECTIONORALIAS
             + ", workers=2, sort=\"miles_i asc\", select(search("
             + COLLECTIONORALIAS
-            + ", q=\"*:*\", partitionKeys=miles_i, sort=\"miles_i asc\", 
fl=\"miles_i\", qt=\"/export\"), convert(miles, kilometers, miles_i) as 
kilometers))";
+            + ", q=\"*:*\", partitionKeys=miles_i, sort=\"miles_i asc\", 
fl=\"miles_i\", path=\"/export\"), convert(miles, kilometers, miles_i) as 
kilometers))";
     paramsLoc = new ModifiableSolrParams();
     paramsLoc.set("expr", expr);
     solrStream = new SolrStream(url, COLLECTIONORALIAS, "/stream", paramsLoc);
diff --git 
a/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/StreamDecoratorTest.java
 
b/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/StreamDecoratorTest.java
index 3359ef2754e..4b1acf26959 100644
--- 
a/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/StreamDecoratorTest.java
+++ 
b/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/StreamDecoratorTest.java
@@ -338,7 +338,7 @@ public class StreamDecoratorTest extends SolrCloudTestCase {
                   + COLLECTIONORALIAS
                   + ", workers=2, sort=\"nullCount desc\", null(search("
                   + COLLECTIONORALIAS
-                  + ", q=*:*, fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc\", 
partitionKeys=id, qt=\"/export\"), by=\"a_i asc\"))");
+                  + ", q=*:*, fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc\", 
partitionKeys=id, path=\"/export\"), by=\"a_i asc\"))");
       stream.setStreamContext(streamContext);
       tuples = getTuples(stream);
       assertEquals(2, tuples.size());
@@ -840,7 +840,7 @@ public class StreamDecoratorTest extends SolrCloudTestCase {
                 + COLLECTIONORALIAS
                 + ", workers=2, sort=\"a_f asc\", having(search("
                 + COLLECTIONORALIAS
-                + ", q=*:*, fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc\", 
partitionKeys=id, qt=\"/export\"), eq(a_i, 9)))");
+                + ", q=*:*, fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc\", 
partitionKeys=id, path=\"/export\"), eq(a_i, 9)))");
     StreamContext context = new StreamContext();
     context.setSolrClientCache(solrClientCache);
     stream.setStreamContext(context);
@@ -856,7 +856,7 @@ public class StreamDecoratorTest extends SolrCloudTestCase {
                 + COLLECTIONORALIAS
                 + ", workers=2, sort=\"a_f asc\", having(search("
                 + COLLECTIONORALIAS
-                + ", q=*:*, fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc\", 
partitionKeys=id, qt=\"/export\"), and(eq(a_i, 9),lt(a_i, 10))))");
+                + ", q=*:*, fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc\", 
partitionKeys=id, path=\"/export\"), and(eq(a_i, 9),lt(a_i, 10))))");
     context = new StreamContext();
     context.setSolrClientCache(solrClientCache);
     stream.setStreamContext(context);
@@ -872,7 +872,7 @@ public class StreamDecoratorTest extends SolrCloudTestCase {
                 + COLLECTIONORALIAS
                 + ", workers=2, sort=\"a_f asc\",having(search("
                 + COLLECTIONORALIAS
-                + ", q=*:*, fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc\", 
partitionKeys=id, qt=\"/export\"), or(eq(a_i, 9),eq(a_i, 8))))");
+                + ", q=*:*, fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc\", 
partitionKeys=id, path=\"/export\"), or(eq(a_i, 9),eq(a_i, 8))))");
     context = new StreamContext();
     context.setSolrClientCache(solrClientCache);
     stream.setStreamContext(context);
@@ -891,7 +891,7 @@ public class StreamDecoratorTest extends SolrCloudTestCase {
                 + COLLECTIONORALIAS
                 + ", workers=2, sort=\"a_f asc\", having(search("
                 + COLLECTIONORALIAS
-                + ", q=*:*, fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc\", 
partitionKeys=id, qt=\"/export\"), and(eq(a_i, 9),not(eq(a_i, 9)))))");
+                + ", q=*:*, fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc\", 
partitionKeys=id, path=\"/export\"), and(eq(a_i, 9),not(eq(a_i, 9)))))");
     context = new StreamContext();
     context.setSolrClientCache(solrClientCache);
     stream.setStreamContext(context);
@@ -905,7 +905,7 @@ public class StreamDecoratorTest extends SolrCloudTestCase {
                 + COLLECTIONORALIAS
                 + ", workers=2, sort=\"a_f asc\",having(search("
                 + COLLECTIONORALIAS
-                + ", q=*:*, fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc\", 
partitionKeys=id, qt=\"/export\"), and(lteq(a_i, 9), gteq(a_i, 8))))");
+                + ", q=*:*, fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc\", 
partitionKeys=id, path=\"/export\"), and(lteq(a_i, 9), gteq(a_i, 8))))");
     context = new StreamContext();
     context.setSolrClientCache(solrClientCache);
     stream.setStreamContext(context);
@@ -925,7 +925,7 @@ public class StreamDecoratorTest extends SolrCloudTestCase {
                 + COLLECTIONORALIAS
                 + ", workers=2, sort=\"a_f asc\", having(rollup(over=a_f, 
sum(a_i), search("
                 + COLLECTIONORALIAS
-                + ", q=*:*, fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc\", 
partitionKeys=a_f, qt=\"/export\")), and(eq(sum(a_i), 9),eq(sum(a_i),9))))");
+                + ", q=*:*, fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc\", 
partitionKeys=a_f, path=\"/export\")), and(eq(sum(a_i), 9),eq(sum(a_i),9))))");
     context = new StreamContext();
     context.setSolrClientCache(solrClientCache);
     stream.setStreamContext(context);
@@ -1102,7 +1102,7 @@ public class StreamDecoratorTest extends 
SolrCloudTestCase {
                   + COLLECTIONORALIAS
                   + ",  search("
                   + COLLECTIONORALIAS
-                  + ", q=*:*, fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc\", 
partitionKeys=\"id\", qt=\"/export\"), on=\"id=a_i\", batchSize=\"2\", 
fl=\"subject\"))");
+                  + ", q=*:*, fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc\", 
partitionKeys=\"id\", path=\"/export\"), on=\"id=a_i\", batchSize=\"2\", 
fl=\"subject\"))");
       stream.setStreamContext(streamContext);
       tuples = getTuples(stream);
 
@@ -1136,7 +1136,7 @@ public class StreamDecoratorTest extends 
SolrCloudTestCase {
                   + COLLECTIONORALIAS
                   + ",  search("
                   + COLLECTIONORALIAS
-                  + ", q=*:*, fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc\", 
partitionKeys=\"id\", qt=\"/export\"), on=\"id=a_i\", batchSize=\"3\", 
fl=\"subject\"))");
+                  + ", q=*:*, fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc\", 
partitionKeys=\"id\", path=\"/export\"), on=\"id=a_i\", batchSize=\"3\", 
fl=\"subject\"))");
       stream.setStreamContext(streamContext);
       tuples = getTuples(stream);
 
@@ -1670,7 +1670,7 @@ public class StreamDecoratorTest extends 
SolrCloudTestCase {
               streamFactory.constructStream(
                   "parallel("
                       + COLLECTIONORALIAS
-                      + ", unique(search(collection1, q=*:*, 
fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc, a_i asc\", partitionKeys=\"a_f\", 
qt=\"/export\"), over=\"a_f\"), workers=\"2\", solrConnection=\""
+                      + ", unique(search(collection1, q=*:*, 
fl=\"id,a_s,a_i,a_f\", sort=\"a_f asc, a_i asc\", partitionKeys=\"a_f\", 
path=\"/export\"), over=\"a_f\"), workers=\"2\", solrConnection=\""
                       + getSolrConnection().toString()
                       + "\", sort=\"a_f asc\")");
       pstream.setStreamContext(streamContext);
@@ -1824,7 +1824,7 @@ public class StreamDecoratorTest extends 
SolrCloudTestCase {
                       + "reduce("
                       + "search("
                       + COLLECTIONORALIAS
-                      + ", q=\"*:*\", fl=\"id,a_s,a_i,a_f\", sort=\"a_s 
asc,a_f asc\", partitionKeys=\"a_s\", qt=\"/export\"), "
+                      + ", q=\"*:*\", fl=\"id,a_s,a_i,a_f\", sort=\"a_s 
asc,a_f asc\", partitionKeys=\"a_s\", path=\"/export\"), "
                       + "by=\"a_s\","
                       + "group(sort=\"a_i asc\", n=\"5\")), "
                       + "workers=\"2\", solrConnection=\""
@@ -1858,7 +1858,7 @@ public class StreamDecoratorTest extends 
SolrCloudTestCase {
                       + "reduce("
                       + "search("
                       + COLLECTIONORALIAS
-                      + ", q=\"*:*\", fl=\"id,a_s,a_i,a_f\", sort=\"a_s 
desc,a_f asc\", partitionKeys=\"a_s\", qt=\"/export\"), "
+                      + ", q=\"*:*\", fl=\"id,a_s,a_i,a_f\", sort=\"a_s 
desc,a_f asc\", partitionKeys=\"a_s\", path=\"/export\"), "
                       + "by=\"a_s\", "
                       + "group(sort=\"a_i desc\", n=\"5\")),"
                       + "workers=\"2\", solrConnection=\""
@@ -1924,7 +1924,7 @@ public class StreamDecoratorTest extends 
SolrCloudTestCase {
                       + "top("
                       + "search("
                       + COLLECTIONORALIAS
-                      + ", q=\"*:*\", fl=\"id,a_s,a_i\", sort=\"a_i asc\", 
partitionKeys=\"a_i\", qt=\"/export\"), "
+                      + ", q=\"*:*\", fl=\"id,a_s,a_i\", sort=\"a_i asc\", 
partitionKeys=\"a_i\", path=\"/export\"), "
                       + "n=\"11\", "
                       + "sort=\"a_i desc\"), workers=\"2\", solrConnection=\""
                       + getSolrConnection().toString()
@@ -1977,9 +1977,9 @@ public class StreamDecoratorTest extends 
SolrCloudTestCase {
                       + COLLECTIONORALIAS
                       + ", merge(search("
                       + COLLECTIONORALIAS
-                      + ", q=\"id:(4 1 8 7 9)\", fl=\"id,a_s,a_i\", sort=\"a_i 
asc\", partitionKeys=\"a_i\", qt=\"/export\"), search("
+                      + ", q=\"id:(4 1 8 7 9)\", fl=\"id,a_s,a_i\", sort=\"a_i 
asc\", partitionKeys=\"a_i\", path=\"/export\"), search("
                       + COLLECTIONORALIAS
-                      + ", q=\"id:(0 2 3 6)\", fl=\"id,a_s,a_i\", sort=\"a_i 
asc\", partitionKeys=\"a_i\", qt=\"/export\"), on=\"a_i asc\"), workers=\"2\", 
solrConnection=\""
+                      + ", q=\"id:(0 2 3 6)\", fl=\"id,a_s,a_i\", sort=\"a_i 
asc\", partitionKeys=\"a_i\", path=\"/export\"), on=\"a_i asc\"), 
workers=\"2\", solrConnection=\""
                       + getSolrConnection().toString()
                       + "\", sort=\"a_i asc\")");
       pstream.setStreamContext(streamContext);
@@ -1997,9 +1997,9 @@ public class StreamDecoratorTest extends 
SolrCloudTestCase {
                       + COLLECTIONORALIAS
                       + ", merge(search("
                       + COLLECTIONORALIAS
-                      + ", q=\"id:(4 1 8 9)\", fl=\"id,a_s,a_i\", sort=\"a_i 
desc\", partitionKeys=\"a_i\", qt=\"/export\"), search("
+                      + ", q=\"id:(4 1 8 9)\", fl=\"id,a_s,a_i\", sort=\"a_i 
desc\", partitionKeys=\"a_i\", path=\"/export\"), search("
                       + COLLECTIONORALIAS
-                      + ", q=\"id:(0 2 3 6)\", fl=\"id,a_s,a_i\", sort=\"a_i 
desc\", partitionKeys=\"a_i\", qt=\"/export\"), on=\"a_i desc\"), 
workers=\"2\", solrConnection=\""
+                      + ", q=\"id:(0 2 3 6)\", fl=\"id,a_s,a_i\", sort=\"a_i 
desc\", partitionKeys=\"a_i\", path=\"/export\"), on=\"a_i desc\"), 
workers=\"2\", solrConnection=\""
                       + getSolrConnection().toString()
                       + "\", sort=\"a_i desc\")");
       pstream.setStreamContext(streamContext);
@@ -2057,7 +2057,7 @@ public class StreamDecoratorTest extends 
SolrCloudTestCase {
                   + "rollup("
                   + "search("
                   + COLLECTIONORALIAS
-                  + ", q=*:*, fl=\"a_s,a_i,a_f\", sort=\"a_s asc\", 
partitionKeys=\"a_s\", qt=\"/export\"),"
+                  + ", q=*:*, fl=\"a_s,a_i,a_f\", sort=\"a_s asc\", 
partitionKeys=\"a_s\", path=\"/export\"),"
                   + "over=\"a_s\","
                   + "sum(a_i),"
                   + "sum(a_f),"
@@ -2200,7 +2200,7 @@ public class StreamDecoratorTest extends 
SolrCloudTestCase {
                   + "hashRollup("
                   + "search("
                   + COLLECTIONORALIAS
-                  + ", q=*:*, fl=\"a_s,a_i,a_f\", sort=\"a_s asc\", 
partitionKeys=\"a_s\", qt=\"/export\"),"
+                  + ", q=*:*, fl=\"a_s,a_i,a_f\", sort=\"a_s asc\", 
partitionKeys=\"a_s\", path=\"/export\"),"
                   + "over=\"a_s\","
                   + "sum(a_i),"
                   + "sum(a_f),"
@@ -3440,7 +3440,7 @@ public class StreamDecoratorTest extends 
SolrCloudTestCase {
     try {
       // Copy all docs to destinationCollection
       String updateExpression =
-          "update(parallelDestinationCollection, batchSize=2, 
search(collection1, q=*:*, fl=\"id,a_s,a_i,a_f,s_multi,i_multi\", sort=\"a_f 
asc, a_i asc\", partitionKeys=\"a_f\", qt=\"/export\"))";
+          "update(parallelDestinationCollection, batchSize=2, 
search(collection1, q=*:*, fl=\"id,a_s,a_i,a_f,s_multi,i_multi\", sort=\"a_f 
asc, a_i asc\", partitionKeys=\"a_f\", path=\"/export\"))";
       TupleStream parallelUpdateStream =
           factory.constructStream(
               "parallel(collection1, "
@@ -3560,7 +3560,7 @@ public class StreamDecoratorTest extends 
SolrCloudTestCase {
     try {
       // Copy all docs to destinationCollection
       String updateExpression =
-          "daemon(update(parallelDestinationCollection1, batchSize=2, 
search(collection1, q=*:*, fl=\"id,a_s,a_i,a_f,s_multi,i_multi\", sort=\"a_f 
asc, a_i asc\", partitionKeys=\"a_f\", qt=\"/export\")), runInterval=\"1000\", 
id=\"test\")";
+          "daemon(update(parallelDestinationCollection1, batchSize=2, 
search(collection1, q=*:*, fl=\"id,a_s,a_i,a_f,s_multi,i_multi\", sort=\"a_f 
asc, a_i asc\", partitionKeys=\"a_f\", path=\"/export\")), 
runInterval=\"1000\", id=\"test\")";
       TupleStream parallelUpdateStream =
           factory.constructStream(
               "parallel(collection1, "
@@ -4070,7 +4070,7 @@ public class StreamDecoratorTest extends 
SolrCloudTestCase {
       String updateExpression =
           "commit(parallelDestinationCollection, batchSize=0, 
solrConnection=\""
               + getSolrConnection().toString()
-              + "\", update(parallelDestinationCollection, batchSize=2, 
search(collection1, q=*:*, fl=\"id,a_s,a_i,a_f,s_multi,i_multi\", sort=\"a_f 
asc, a_i asc\", partitionKeys=\"a_f\", qt=\"/export\")))";
+              + "\", update(parallelDestinationCollection, batchSize=2, 
search(collection1, q=*:*, fl=\"id,a_s,a_i,a_f,s_multi,i_multi\", sort=\"a_f 
asc, a_i asc\", partitionKeys=\"a_f\", path=\"/export\")))";
       TupleStream parallelUpdateStream =
           factory.constructStream(
               "parallel(collection1, "
@@ -4192,7 +4192,7 @@ public class StreamDecoratorTest extends 
SolrCloudTestCase {
       String updateExpression =
           "daemon(commit(parallelDestinationCollection1, batchSize=0, 
solrConnection=\""
               + getSolrConnection().toString()
-              + "\", update(parallelDestinationCollection1, batchSize=2, 
search(collection1, q=*:*, fl=\"id,a_s,a_i,a_f,s_multi,i_multi\", sort=\"a_f 
asc, a_i asc\", partitionKeys=\"a_f\", qt=\"/export\"))), runInterval=\"1000\", 
id=\"test\")";
+              + "\", update(parallelDestinationCollection1, batchSize=2, 
search(collection1, q=*:*, fl=\"id,a_s,a_i,a_f,s_multi,i_multi\", sort=\"a_f 
asc, a_i asc\", partitionKeys=\"a_f\", path=\"/export\"))), 
runInterval=\"1000\", id=\"test\")";
       TupleStream parallelUpdateStream =
           factory.constructStream(
               "parallel(collection1, "
@@ -4756,7 +4756,7 @@ public class StreamDecoratorTest extends 
SolrCloudTestCase {
             .withFunctionName("update", UpdateStream.class);
 
     String executorExpression =
-        "parallel(workQueue1, workers=2, sort=\"EOF asc\", executor(threads=3, 
queueSize=100, search(workQueue1, q=\"*:*\", fl=\"id, expr_s\", rows=1000, 
partitionKeys=id, sort=\"id desc\", qt=\"/export\")))";
+        "parallel(workQueue1, workers=2, sort=\"EOF asc\", executor(threads=3, 
queueSize=100, search(workQueue1, q=\"*:*\", fl=\"id, expr_s\", rows=1000, 
partitionKeys=id, sort=\"id desc\", path=\"/export\")))";
     executorStream = factory.constructStream(executorExpression);
 
     StreamContext context = new StreamContext();
@@ -4830,8 +4830,8 @@ public class StreamDecoratorTest extends 
SolrCloudTestCase {
               "parallel("
                   + "collection1, "
                   + "intersect("
-                  + "search(collection1, q=a_s:(setA || setAB), 
fl=\"id,a_s,a_i\", sort=\"a_i asc, a_s asc\", partitionKeys=\"a_i\", 
qt=\"/export\"),"
-                  + "search(collection1, q=a_s:(setB || setAB), 
fl=\"id,a_s,a_i\", sort=\"a_i asc\", partitionKeys=\"a_i\", qt=\"/export\"),"
+                  + "search(collection1, q=a_s:(setA || setAB), 
fl=\"id,a_s,a_i\", sort=\"a_i asc, a_s asc\", partitionKeys=\"a_i\", 
path=\"/export\"),"
+                  + "search(collection1, q=a_s:(setB || setAB), 
fl=\"id,a_s,a_i\", sort=\"a_i asc\", partitionKeys=\"a_i\", path=\"/export\"),"
                   + "on=\"a_i\"),"
                   + "workers=\"2\", solrConnection=\""
                   + getSolrConnection().toString()
@@ -5082,8 +5082,8 @@ public class StreamDecoratorTest extends 
SolrCloudTestCase {
               "parallel("
                   + "collection1, "
                   + "complement("
-                  + "search(collection1, q=a_s:(setA || setAB), 
fl=\"id,a_s,a_i\", sort=\"a_i asc, a_s asc\", partitionKeys=\"a_i\", 
qt=\"/export\"),"
-                  + "search(collection1, q=a_s:(setB || setAB), 
fl=\"id,a_s,a_i\", sort=\"a_i asc\", partitionKeys=\"a_i\", qt=\"/export\"),"
+                  + "search(collection1, q=a_s:(setA || setAB), 
fl=\"id,a_s,a_i\", sort=\"a_i asc, a_s asc\", partitionKeys=\"a_i\", 
path=\"/export\"),"
+                  + "search(collection1, q=a_s:(setB || setAB), 
fl=\"id,a_s,a_i\", sort=\"a_i asc\", partitionKeys=\"a_i\", path=\"/export\"),"
                   + "on=\"a_i\"),"
                   + "workers=\"2\", solrConnection=\""
                   + getSolrConnection().toString()
@@ -5271,7 +5271,7 @@ public class StreamDecoratorTest extends 
SolrCloudTestCase {
               + ",batchSize=99,              "
               + "              search("
               + COLLECTIONORALIAS
-              + ",qt=\"/export\",     "
+              + ",path=\"/export\",     "
               + "                     q=\"deletable_s:yup\",                   
 "
               + "                     sort=\"id asc\",fl=\"id,_version_\"      
 "
               + "              ) ) )                                           
 ";
diff --git 
a/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/StreamExpressionTest.java
 
b/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/StreamExpressionTest.java
index fbe02ce3604..1ec315c8da3 100644
--- 
a/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/StreamExpressionTest.java
+++ 
b/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/StreamExpressionTest.java
@@ -334,6 +334,23 @@ public class StreamExpressionTest extends 
SolrCloudTestCase {
       assertDouble(tuples.get(4), "a_f", 4);
       assertString(tuples.get(4), "a_s", "hello4");
 
+      // SOLR-18332: the legacy 'qt' parameter must continue to select the 
/export-capable
+      // path server-side (SearchFacadeStream). 'partitionKeys' is only 
accepted on that path,
+      // so this also exercises that guard.
+      solrParams = new ModifiableSolrParams();
+      solrParams.add(
+          "expr",
+          "sort(search("
+              + COLLECTIONORALIAS
+              + ", q=\"*:*\", fl=\"id,a_i\", sort=\"a_i asc\", 
partitionKeys=\"id\", qt=\"/export\"), by=\"a_i asc\")");
+      solrStream = new SolrStream(shardUrls.get(0), "/stream", solrParams);
+      solrStream.setStreamContext(streamContext);
+      tuples = getTuples(solrStream);
+      assertEquals(5, tuples.size());
+      assertOrder(tuples, 0, 1, 2, 3, 4);
+      assertLong(tuples.get(0), "a_i", 0);
+      assertLong(tuples.get(4), "a_i", 4);
+
     } finally {
       solrClientCache.close();
     }
@@ -580,7 +597,7 @@ public class StreamExpressionTest extends SolrCloudTestCase 
{
           StreamExpressionParser.parse(
               "search("
                   + COLLECTIONORALIAS
-                  + ", q=*:*, fl=\"id,a_s,a_i,a_f, s_multi, i_multi\", 
qt=\"/export\", sort=\"a_i asc\")");
+                  + ", q=*:*, fl=\"id,a_s,a_i,a_f, s_multi, i_multi\", 
path=\"/export\", sort=\"a_i asc\")");
       stream = new CloudSolrStream(expression, factory);
       stream.setStreamContext(streamContext);
       tuples = getTuples(stream);
@@ -608,7 +625,7 @@ public class StreamExpressionTest extends SolrCloudTestCase 
{
           StreamExpressionParser.parse(
               "search("
                   + COLLECTIONORALIAS
-                  + ", q=*:*, fl=\"id,a_s,a_i,a_f, s_multi, i_multi\", 
qt=\"/export\", sort=\"a_s asc\")");
+                  + ", q=*:*, fl=\"id,a_s,a_i,a_f, s_multi, i_multi\", 
path=\"/export\", sort=\"a_s asc\")");
       stream = new CloudSolrStream(expression, factory);
       stream.setStreamContext(streamContext);
       tuples = getTuples(stream);
@@ -621,7 +638,7 @@ public class StreamExpressionTest extends SolrCloudTestCase 
{
           StreamExpressionParser.parse(
               "search("
                   + COLLECTIONORALIAS
-                  + ", q=*:*, fl=\"id,a_s,a_i,a_f, s_multi, i_multi\", 
qt=\"/export\", sort=\"a_s desc\")");
+                  + ", q=*:*, fl=\"id,a_s,a_i,a_f, s_multi, i_multi\", 
path=\"/export\", sort=\"a_s desc\")");
       stream = new CloudSolrStream(expression, factory);
       stream.setStreamContext(streamContext);
       tuples = getTuples(stream);
@@ -1336,7 +1353,7 @@ public class StreamExpressionTest extends 
SolrCloudTestCase {
     ModifiableSolrParams paramsLoc = new ModifiableSolrParams();
     String expr =
         "rollup("
-            + "  search(collection1, q=*:*, fl=\"a_s,a_i,a_f\", sort=\"a_s 
asc\", qt=\"/export\"),"
+            + "  search(collection1, q=*:*, fl=\"a_s,a_i,a_f\", sort=\"a_s 
asc\", path=\"/export\"),"
             + "  over=\"a_s\", std(a_i), std(a_f), count(*)"
             + ")";
     paramsLoc.set("expr", expr);
@@ -2230,7 +2247,7 @@ public class StreamExpressionTest extends 
SolrCloudTestCase {
       solrParams = new ModifiableSolrParams();
       solrParams.add(
           "expr",
-          "search(\"collection1, collection2\", q=\"*:*\", fl=\"id, a_i\", 
sort=\"a_i asc\", qt=\"/export\")");
+          "search(\"collection1, collection2\", q=\"*:*\", fl=\"id, a_i\", 
sort=\"a_i asc\", path=\"/export\")");
       solrStream = new SolrStream(shardUrls.get(0), "/stream", solrParams);
       solrStream.setStreamContext(streamContext);
       tuples = getTuples(solrStream);
@@ -2273,7 +2290,7 @@ public class StreamExpressionTest extends 
SolrCloudTestCase {
       solrParams = new ModifiableSolrParams();
       solrParams.add(
           "expr",
-          "parallel(collection1, sort=\"a_i asc\", workers=2, 
search(\"collection1, collection2\", q=\"*:*\", fl=\"id, a_i\", sort=\"a_i 
asc\", qt=\"/export\", partitionKeys=\"a_s\"))");
+          "parallel(collection1, sort=\"a_i asc\", workers=2, 
search(\"collection1, collection2\", q=\"*:*\", fl=\"id, a_i\", sort=\"a_i 
asc\", path=\"/export\", partitionKeys=\"a_s\"))");
       solrStream = new SolrStream(shardUrls.get(0), "/stream", solrParams);
       solrStream.setStreamContext(streamContext);
       tuples = getTuples(solrStream);
diff --git 
a/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/StreamingTest.java
 
b/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/StreamingTest.java
index 54dd1bbf677..d4e50c00fb0 100644
--- 
a/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/StreamingTest.java
+++ 
b/solr/solrj-streaming/src/test/org/apache/solr/client/solrj/io/stream/StreamingTest.java
@@ -2129,7 +2129,7 @@ public class StreamingTest extends SolrCloudTestCase {
           "expr",
           "rollup(search("
               + COLLECTIONORALIAS
-              + ",q=\"*:*\",fl=\"a_s,a_i,a_f,b_f\",sort=\"a_s 
asc\",partitionKeys=\"a_s\", 
qt=\"/export\"),over=\"a_s\",sum(a_i),sum(a_f),min(a_i),min(a_f),max(a_i),max(a_f),avg(a_i),avg(a_f),count(*),missing(b_f))\n");
+              + ",q=\"*:*\",fl=\"a_s,a_i,a_f,b_f\",sort=\"a_s 
asc\",partitionKeys=\"a_s\", 
path=\"/export\"),over=\"a_s\",sum(a_i),sum(a_f),min(a_i),min(a_f),max(a_i),max(a_f),avg(a_i),avg(a_f),count(*),missing(b_f))\n");
       SolrStream solrStream = new SolrStream(shardUrls.get(0), "/stream", 
solrParams);
       streamContext = new StreamContext();
       solrStream.setStreamContext(streamContext);
@@ -3176,7 +3176,7 @@ public class StreamingTest extends SolrCloudTestCase {
     String expr =
         "search("
             + MULTI_REPLICA_COLLECTIONORALIAS
-            + ",q=*:*,fl=\"a_i\", qt=\"/export\", sort=\"a_i asc\")";
+            + ",q=*:*,fl=\"a_i\", path=\"/export\", sort=\"a_i asc\")";
     try (CloudSolrStream stream =
         new CloudSolrStream(StreamExpressionParser.parse(expr), 
streamFactory)) {
       stream.setStreamContext(streamContext);

Reply via email to