diff --git a/changelog/unreleased/SOLR-17985-fix-slow-no-rows-queries.yml b/changelog/unreleased/SOLR-17985-fix-slow-no-rows-queries.yml new file mode 100644 index 00000000000..f7d5f2cee52 --- /dev/null +++ b/changelog/unreleased/SOLR-17985-fix-slow-no-rows-queries.yml @@ -0,0 +1,10 @@ +# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc +title: Make distributed no-rows queries fast again +type: fixed # added, changed, fixed, deprecated, removed, dependency_update, security, other +authors: + - name: Houston Putman + nick: HoustonPutman + url: https://home.apache.org/phonebook.html?uid=houston +links: + - name: SOLR-17985 + url: https://issues.apache.org/jira/browse/SOLR-17985 diff --git a/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java b/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java index cf174f21217..30875caa70f 100644 --- a/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java +++ b/solr/core/src/java/org/apache/solr/handler/component/QueryComponent.java @@ -832,20 +832,24 @@ protected void createMainQuery(ResponseBuilder rb) { // perhaps we shouldn't attempt to parse the query at this level? // Alternate Idea: instead of specifying all these things at the upper level, // we could just specify that this is a shard request. + int shardRows; if (rb.shards_rows > -1) { // if the client set shards.rows set this explicity - sreq.params.set(CommonParams.ROWS, rb.shards_rows); + shardRows = rb.shards_rows; } else { - // what if rows<0 as it is allowed for grouped request?? - sreq.params.set( - CommonParams.ROWS, rb.getSortSpec().getOffset() + rb.getSortSpec().getCount()); + shardRows = rb.getSortSpec().getCount(); + // If rows = -1 (grouped requests) or rows = 0, then there is no need to add the offset. + if (shardRows > 0) { + shardRows += rb.getSortSpec().getOffset(); + } } + sreq.params.set(CommonParams.ROWS, shardRows); sreq.params.set(ResponseBuilder.FIELD_SORT_VALUES, "true"); boolean shardQueryIncludeScore = (rb.getFieldFlags() & SolrIndexSearcher.GET_SCORES) != 0 - || rb.getSortSpec().includesScore(); + || (shardRows != 0 && rb.getSortSpec().includesScore()); StringBuilder additionalFL = new StringBuilder(); boolean additionalAdded = false; if (rb.onePassDistributedQuery) { diff --git a/solr/core/src/test/org/apache/solr/TestDistributedSearch.java b/solr/core/src/test/org/apache/solr/TestDistributedSearch.java index 72d0493be55..4993a96c30e 100644 --- a/solr/core/src/test/org/apache/solr/TestDistributedSearch.java +++ b/solr/core/src/test/org/apache/solr/TestDistributedSearch.java @@ -1550,6 +1550,7 @@ public void test() throws Exception { // Check Info is added to for each shard ModifiableSolrParams q = new ModifiableSolrParams(); q.set("q", "*:*"); + q.set("rows", "0"); q.set(ShardParams.SHARDS_INFO, true); setDistributedParams(q); rsp = queryRandomShard(q); @@ -1560,6 +1561,13 @@ public void test() throws Exception { assertNotNull("missing shard info", sinfo); assertEquals( "should have an entry for each shard [" + sinfo + "] " + shards, cnt, sinfo.size()); + // We are setting rows=0, so scores should not be collected + for (int i = 0; i < cnt; i++) { + String shard = sinfo.getName(i); + assertNull( + "should not have any score information (maxScore) in the shard info: " + shard, + ((Map) sinfo.get(shard)).get("maxScore")); + } // test shards.tolerant=true