You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ds...@apache.org on 2026/05/07 12:57:59 UTC
(lucene) branch branch_10x updated (505391fb900 -> eb8b1b460de)
This is an automated email from the ASF dual-hosted git repository.
dsmiley pushed a change to branch branch_10x
in repository https://gitbox.apache.org/repos/asf/lucene.git
from 505391fb900 Eliminate redundant cardinality() pass in MaxScoreBulkScorer (#15971)
new 8de08956217 Optimize IndexSearcher.count() to rewrite the query once (#16001)
new eb8b1b460de Optimize QueryVisitor.EMPTY_VISITOR (#16003)
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
lucene/CHANGES.txt | 1 +
.../org/apache/lucene/search/IndexSearcher.java | 49 +++++++++++++---------
.../org/apache/lucene/search/QueryVisitor.java | 8 +++-
3 files changed, 38 insertions(+), 20 deletions(-)
(lucene) 01/02: Optimize IndexSearcher.count() to rewrite the query once (#16001)
Posted by ds...@apache.org.
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/lucene.git
commit 8de0895621736e1756e815ff0c6aaf8ec29c7e67
Author: David Smiley <ds...@apache.org>
AuthorDate: Tue May 5 23:14:45 2026 -0400
Optimize IndexSearcher.count() to rewrite the query once (#16001)
(cherry picked from commit 038e16787158a95576262842f87302b3b81032de)
---
lucene/CHANGES.txt | 1 +
.../org/apache/lucene/search/IndexSearcher.java | 49 +++++++++++++---------
2 files changed, 31 insertions(+), 19 deletions(-)
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index aac915f91c7..cb9d0bb3cd2 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -106,6 +106,7 @@ Optimizations
* GITHUB#15732: Prevent writing vectors twice during merging HNSW graphs by allowing doing deferred work after calling
merge for vectors is finshed. (Ignacio Vera)
+* GITHUB#16001: IndexSearcher.count() was calling query.rewrite twice, a regression since v9.10 (David Smiley)
Bug Fixes
---------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java b/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
index 972c4a5ef64..ffe41fcaf9f 100644
--- a/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
+++ b/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
@@ -499,28 +499,39 @@ public class IndexSearcher {
* possible.
*/
public int count(Query query) throws IOException {
- // Rewrite query before optimization check
+ // CSQ.rewrite may simplify the query -- don't need scores
query = rewrite(new ConstantScoreQuery(query));
- if (query instanceof ConstantScoreQuery csq) {
- query = csq.getQuery();
- }
- // Check if two clause disjunction optimization applies
- if (query instanceof BooleanQuery booleanQuery
- && this.reader.hasDeletions() == false
- && booleanQuery.isTwoClausePureDisjunctionWithTerms()) {
- Query[] queries = booleanQuery.rewriteTwoClauseDisjunctionWithTermsForCount(this);
- int countTerm1 = count(queries[0]);
- int countTerm2 = count(queries[1]);
- if (countTerm1 == 0 || countTerm2 == 0) {
- return Math.max(countTerm1, countTerm2);
- // Only apply optimization if the intersection is significantly smaller than the union
- } else if ((double) Math.min(countTerm1, countTerm2) / Math.max(countTerm1, countTerm2)
- < 0.1) {
- return countTerm1 + countTerm2 - count(queries[2]);
+ {
+ // Unwrap CSQ to check for optimizations on the inner query
+ Query innerQuery = query;
+ if (innerQuery instanceof ConstantScoreQuery csq) {
+ innerQuery = csq.getQuery();
+ }
+
+ // Check if two clause disjunction optimization applies
+ if (innerQuery instanceof BooleanQuery booleanQuery
+ && this.reader.hasDeletions() == false
+ && booleanQuery.isTwoClausePureDisjunctionWithTerms()) {
+ Query[] queries = booleanQuery.rewriteTwoClauseDisjunctionWithTermsForCount(this);
+ int countTerm1 = count(queries[0]);
+ int countTerm2 = count(queries[1]);
+ if (countTerm1 == 0 || countTerm2 == 0) {
+ return Math.max(countTerm1, countTerm2);
+ // Only apply optimization if the intersection is significantly smaller than the union
+ } else if ((double) Math.min(countTerm1, countTerm2) / Math.max(countTerm1, countTerm2)
+ < 0.1) {
+ return countTerm1 + countTerm2 - count(queries[2]);
+ }
}
}
- return search(new ConstantScoreQuery(query), new TotalHitCountCollectorManager(getSlices()));
+
+ // Use the already-rewritten query directly, avoiding a redundant rewrite in search(query,
+ // collector)
+ var collectorManager = new TotalHitCountCollectorManager(getSlices());
+ var firstCollector = collectorManager.newCollector();
+ final Weight weight = createWeight(query, firstCollector.scoreMode(), 1);
+ return search(weight, collectorManager, firstCollector);
}
/**
@@ -970,7 +981,7 @@ public class IndexSearcher {
/**
* Creates a {@link Weight} for the given query, potentially adding caching if possible and
- * configured.
+ * configured. The query is assumed to have been {@link #rewrite(Query)}-en already.
*
* @lucene.experimental
*/
(lucene) 02/02: Optimize QueryVisitor.EMPTY_VISITOR (#16003)
Posted by ds...@apache.org.
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/lucene.git
commit eb8b1b460deebf552ed330f15097dfbe27062e86
Author: David Smiley <ds...@apache.org>
AuthorDate: Tue May 5 23:30:28 2026 -0400
Optimize QueryVisitor.EMPTY_VISITOR (#16003)
Return false for acceptField.
(cherry picked from commit b03bd1fe685572fd6a036ee03bcdb50e1c6d4108)
---
lucene/core/src/java/org/apache/lucene/search/QueryVisitor.java | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/lucene/core/src/java/org/apache/lucene/search/QueryVisitor.java b/lucene/core/src/java/org/apache/lucene/search/QueryVisitor.java
index 644e21a371a..4b362edfca5 100644
--- a/lucene/core/src/java/org/apache/lucene/search/QueryVisitor.java
+++ b/lucene/core/src/java/org/apache/lucene/search/QueryVisitor.java
@@ -99,5 +99,11 @@ public abstract class QueryVisitor {
}
/** A QueryVisitor implementation that does nothing */
- public static final QueryVisitor EMPTY_VISITOR = new QueryVisitor() {};
+ public static final QueryVisitor EMPTY_VISITOR =
+ new QueryVisitor() {
+ @Override
+ public boolean acceptField(String field) {
+ return false;
+ }
+ };
}