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

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


The following commit(s) were added to refs/heads/main by this push:
     new ac74ced99e2 SOLR-17699: Fix {!frange} perf regression in disjunction 
(#3259)
ac74ced99e2 is described below

commit ac74ced99e288f74a18655ec4cd2f205b976ca54
Author: David Smiley <[email protected]>
AuthorDate: Mon Mar 17 21:26:34 2025 -0400

    SOLR-17699: Fix {!frange} perf regression in disjunction (#3259)
    
    Since 9.0 with "frange" function queries when in a disjunction (OR).  
TwoPhaseIterator must be used; was iterating all docs instead.
---
 solr/CHANGES.txt                                         |  2 ++
 .../solr/search/function/ValueSourceRangeFilter.java     |  2 +-
 solr/core/src/test/org/apache/solr/core/SOLR749Test.java | 16 ++++++++++++++++
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index d46b9e8e090..c7966f27ad8 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -212,6 +212,8 @@ Bug Fixes
 * SOLR-17700: Use Core Operation lock when unloading cores. This fixes errors 
that occur when a collection deletion and reload
   occur at the same time. (Houston Putman)
 
+* SOLR-17699: Fixed performance regression since 9.0 with "frange" queries 
embedded in other queries.
+  May also affect some numeric range queries when the minimum is negative.  
(David Smiley)
 
 Dependency Upgrades
 ---------------------
diff --git 
a/solr/core/src/java/org/apache/solr/search/function/ValueSourceRangeFilter.java
 
b/solr/core/src/java/org/apache/solr/search/function/ValueSourceRangeFilter.java
index 0deb5744e8d..6c0d30022e8 100644
--- 
a/solr/core/src/java/org/apache/solr/search/function/ValueSourceRangeFilter.java
+++ 
b/solr/core/src/java/org/apache/solr/search/function/ValueSourceRangeFilter.java
@@ -116,7 +116,7 @@ public class ValueSourceRangeFilter extends Query {
           valueSource
               .getValues(vsContext, context)
               .getRangeScorer(this, context, lowerVal, upperVal, includeLower, 
includeUpper);
-      return new ConstantScoreScorer(this, score(), scoreMode, 
scorer.iterator());
+      return new ConstantScoreScorer(this, score(), scoreMode, 
scorer.twoPhaseIterator());
     }
 
     @Override
diff --git a/solr/core/src/test/org/apache/solr/core/SOLR749Test.java 
b/solr/core/src/test/org/apache/solr/core/SOLR749Test.java
index 7af7beb55bb..4d8dcbee9af 100644
--- a/solr/core/src/test/org/apache/solr/core/SOLR749Test.java
+++ b/solr/core/src/test/org/apache/solr/core/SOLR749Test.java
@@ -160,6 +160,22 @@ public class SOLR749Test extends SolrTestCaseJ4 {
           "//result[@numFound=5]");
       assertEquals(10, 
CountUsageValueSourceParser.getAndClearCount("lowCost"));
       assertEquals(9, 
CountUsageValueSourceParser.getAndClearCount("lastFilter"));
+
+      // Tests that TwoPhaseIterator is employed optimally:
+      // Tests a disjunction (OR), that the function isn't called if another 
clause matches
+      // note: map(countUsage(frange_or,0),0,0,id_i1) == return "id_i1" value 
& keep track of access
+      assertQ(
+          "frange with disjunction",
+          req(
+              "q",
+              "{!notfoo}id_i1:[0 TO 49]",
+              "fq",
+              "{!notfoo cache=false}id_i1:[20 TO 39] OR {!frange l=35 u=40 
v='map(countUsage(frange_or,0),0,0,id_i1)'}"),
+          "//result[@numFound=21]");
+      // the first fq range query matches 20 docs.
+      // the frange grabbed one additional doc (#40), hence result is 21.
+      // the frange(countUsage) should test 50 docs minus the 20 from the 
numeric range
+      assertEquals(50 - 20, 
CountUsageValueSourceParser.getAndClearCount("frange_or"));
     } finally {
       CountUsageValueSourceParser.clearCounters();
     }

Reply via email to