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();
}