You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ro...@apache.org on 2019/03/14 15:04:37 UTC
[lucene-solr] branch master updated: LUCENE-3041: QueryVisitor
(#581)
This is an automated email from the ASF dual-hosted git repository.
romseygeek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git
The following commit(s) were added to refs/heads/master by this push:
new fbd0516 LUCENE-3041: QueryVisitor (#581)
fbd0516 is described below
commit fbd05167f455e3ce2b2ead50336e2b9c2521cd6c
Author: Alan Woodward <ro...@gmail.com>
AuthorDate: Thu Mar 14 15:04:33 2019 +0000
LUCENE-3041: QueryVisitor (#581)
This commit adds an introspection API to Query, allowing users to traverse
the nested structure of a query and examine its leaves. It replaces the existing
`extractTerms` method on Weight, and alters some highlighting code to use
the new API
---
lucene/CHANGES.txt | 13 +
.../classification/utils/NearestFuzzyQuery.java | 6 +
.../org/apache/lucene/document/FeatureQuery.java | 22 +-
.../lucene/document/LatLonDocValuesBoxQuery.java | 8 +
.../document/LatLonDocValuesDistanceQuery.java | 8 +
.../document/LatLonPointDistanceFeatureQuery.java | 13 +-
.../lucene/document/LatLonPointDistanceQuery.java | 8 +
.../lucene/document/LatLonPointInPolygonQuery.java | 8 +
.../lucene/document/LongDistanceFeatureQuery.java | 13 +-
.../apache/lucene/document/RangeFieldQuery.java | 10 +-
.../document/SortedNumericDocValuesRangeQuery.java | 8 +
.../document/SortedSetDocValuesRangeQuery.java | 8 +
.../org/apache/lucene/search/AutomatonQuery.java | 9 +-
.../org/apache/lucene/search/BlendedTermQuery.java | 11 +-
.../org/apache/lucene/search/BooleanQuery.java | 12 +
.../org/apache/lucene/search/BooleanWeight.java | 13 -
.../java/org/apache/lucene/search/BoostQuery.java | 5 +
.../apache/lucene/search/ConstantScoreQuery.java | 5 +
.../apache/lucene/search/ConstantScoreWeight.java | 9 -
.../apache/lucene/search/DisjunctionMaxQuery.java | 19 +-
.../lucene/search/DocValuesFieldExistsQuery.java | 7 +
.../lucene/search/DocValuesRewriteMethod.java | 7 +
.../org/apache/lucene/search/FilterWeight.java | 7 -
.../java/org/apache/lucene/search/FuzzyQuery.java | 20 +-
.../org/apache/lucene/search/FuzzyTermsEnum.java | 62 +++-
.../lucene/search/IndexOrDocValuesQuery.java | 14 +-
.../org/apache/lucene/search/LRUQueryCache.java | 6 -
.../apache/lucene/search/MatchAllDocsQuery.java | 5 +
.../org/apache/lucene/search/MatchNoDocsQuery.java | 11 +-
.../org/apache/lucene/search/MultiPhraseQuery.java | 21 +-
.../search/MultiTermQueryConstantScoreWrapper.java | 7 +
.../org/apache/lucene/search/NGramPhraseQuery.java | 5 +
.../lucene/search/NormsFieldExistsQuery.java | 7 +
.../java/org/apache/lucene/search/PhraseQuery.java | 19 +-
.../org/apache/lucene/search/PointInSetQuery.java | 7 +
.../org/apache/lucene/search/PointRangeQuery.java | 7 +
.../src/java/org/apache/lucene/search/Query.java | 6 +
.../org/apache/lucene/search/QueryVisitor.java | 94 ++++++
.../org/apache/lucene/search/SynonymQuery.java | 25 +-
.../org/apache/lucene/search/TermInSetQuery.java | 25 +-
.../java/org/apache/lucene/search/TermQuery.java | 13 +-
.../src/java/org/apache/lucene/search/Weight.java | 10 -
.../org/apache/lucene/search/package-info.java | 6 -
.../lucene/search/spans/FieldMaskingSpanQuery.java | 15 +-
.../apache/lucene/search/spans/SpanBoostQuery.java | 9 +
.../lucene/search/spans/SpanContainQuery.java | 31 +-
.../search/spans/SpanMultiTermQueryWrapper.java | 10 +-
.../apache/lucene/search/spans/SpanNearQuery.java | 31 +-
.../apache/lucene/search/spans/SpanNotQuery.java | 19 +-
.../apache/lucene/search/spans/SpanOrQuery.java | 21 +-
.../search/spans/SpanPositionCheckQuery.java | 15 +-
.../apache/lucene/search/spans/SpanTermQuery.java | 16 +-
.../apache/lucene/document/TestFeatureField.java | 26 --
.../apache/lucene/search/JustCompileSearch.java | 12 +-
.../lucene/search/TestBoolean2ScorerSupplier.java | 10 +-
.../org/apache/lucene/search/TestBooleanQuery.java | 45 ++-
.../apache/lucene/search/TestBooleanScorer.java | 11 +-
.../apache/lucene/search/TestConjunctionDISI.java | 7 -
.../lucene/search/TestConstantScoreQuery.java | 22 +-
.../apache/lucene/search/TestLRUQueryCache.java | 31 +-
.../lucene/search/TestMaxScoreSumPropagator.java | 7 -
.../lucene/search/TestMultiTermQueryRewrites.java | 5 +
.../org/apache/lucene/search/TestNeedsScores.java | 5 +
.../org/apache/lucene/search/TestPrefixRandom.java | 5 +
.../apache/lucene/search/TestQueryRescorer.java | 10 +-
.../org/apache/lucene/search/TestQueryVisitor.java | 333 +++++++++++++++++++++
.../apache/lucene/search/TestRegexpRandom2.java | 7 +-
.../org/apache/lucene/search/TestScorerPerf.java | 7 +-
.../org/apache/lucene/search/TestSortRandom.java | 5 +
.../TestUsageTrackingFilterCachingPolicy.java | 5 +
.../org/apache/lucene/search/TestWANDScorer.java | 5 +
.../search/spans/JustCompileSearchSpans.java | 6 +
.../search/spans/TestFieldMaskingSpanQuery.java | 13 +-
.../org/apache/lucene/facet/DrillDownQuery.java | 6 +
.../apache/lucene/facet/DrillSidewaysQuery.java | 11 +-
.../org/apache/lucene/facet/range/DoubleRange.java | 6 +
.../org/apache/lucene/facet/range/LongRange.java | 6 +
.../org/apache/lucene/facet/TestDrillSideways.java | 6 +
.../lucene/facet/range/TestRangeFacetCounts.java | 6 +
.../search/highlight/QueryTermExtractor.java | 90 +++---
.../highlight/WeightedSpanTermExtractor.java | 7 +-
.../uhighlight/MemoryIndexOffsetStrategy.java | 13 +-
.../search/uhighlight/MultiTermHighlighting.java | 236 +++++++--------
.../lucene/search/uhighlight/OffsetsEnum.java | 27 +-
.../lucene/search/uhighlight/PhraseHelper.java | 33 +-
.../search/uhighlight/UnifiedHighlighter.java | 23 +-
.../lucene/search/highlight/HighlighterTest.java | 6 +
.../highlight/custom/HighlightCustomQueryTest.java | 16 +-
.../uhighlight/TestUnifiedHighlighterMTQ.java | 17 +-
.../TestUnifiedHighlighterStrictPhrases.java | 6 +
.../search/vectorhighlight/FieldQueryTest.java | 8 +
.../lucene/search/join/GlobalOrdinalsQuery.java | 10 +-
.../search/join/GlobalOrdinalsWithScoreQuery.java | 10 +-
.../search/join/ParentChildrenBlockJoinQuery.java | 13 +-
.../search/join/PointInSetIncludingScoreQuery.java | 14 +-
.../search/join/TermsIncludingScoreQuery.java | 13 +-
.../org/apache/lucene/search/join/TermsQuery.java | 6 +
.../lucene/search/join/ToChildBlockJoinQuery.java | 9 +-
.../lucene/search/join/ToParentBlockJoinQuery.java | 6 +
.../apache/lucene/search/join/TestBlockJoin.java | 33 +-
.../apache/lucene/search/join/TestJoinUtil.java | 16 +-
.../search/TestDiversifiedTopDocsCollector.java | 13 +-
.../apache/lucene/queries/CommonTermsQuery.java | 12 +-
.../queries/function/FunctionMatchQuery.java | 6 +
.../lucene/queries/function/FunctionQuery.java | 12 +-
.../queries/function/FunctionRangeQuery.java | 13 +-
.../queries/function/FunctionScoreQuery.java | 14 +-
.../lucene/queries/mlt/MoreLikeThisQuery.java | 18 +-
.../lucene/queries/payloads/PayloadScoreQuery.java | 13 +-
.../queries/payloads/SpanPayloadCheckQuery.java | 16 +-
.../complexPhrase/ComplexPhraseQueryParser.java | 6 +
.../surround/query/DistanceRewriteQuery.java | 8 +
.../surround/query/SimpleTermRewriteQuery.java | 14 +-
.../queryparser/classic/TestMultiAnalyzer.java | 17 +-
.../apache/lucene/document/LatLonShapeQuery.java | 8 +
.../lucene/sandbox/queries/FuzzyLikeThisQuery.java | 8 +-
.../java/org/apache/lucene/search/BM25FQuery.java | 14 +-
.../org/apache/lucene/search/CoveringQuery.java | 17 +-
.../lucene/search/DocValuesNumbersQuery.java | 8 +
.../apache/lucene/search/DocValuesTermsQuery.java | 9 +-
.../apache/lucene/search/TermAutomatonQuery.java | 23 +-
.../intervals/ConjunctionIntervalsSource.java | 10 +-
.../intervals/DifferenceIntervalsSource.java | 10 +-
.../intervals/DisjunctionIntervalsSource.java | 11 +-
.../search/intervals/ExtendedIntervalsSource.java | 7 +-
.../search/intervals/FilteredIntervalsSource.java | 7 +-
.../intervals/FixedFieldIntervalsSource.java | 7 +-
.../lucene/search/intervals/IntervalQuery.java | 15 +-
.../lucene/search/intervals/IntervalsSource.java | 9 +-
.../MinimumShouldMatchIntervalsSource.java | 10 +-
.../search/intervals/MultiTermIntervalsSource.java | 5 +-
.../search/intervals/OffsetIntervalsSource.java | 7 +-
.../search/intervals/TermIntervalsSource.java | 6 +-
.../sandbox/queries/FuzzyLikeThisQueryTest.java | 16 +-
.../lucene/search/TestTermAutomatonQuery.java | 5 +
.../spatial/composite/CompositeVerifyQuery.java | 6 +
.../composite/IntersectsRPTVerifyQuery.java | 6 +
.../spatial/prefix/AbstractPrefixTreeQuery.java | 8 +
.../spatial/serialized/SerializedDVStrategy.java | 6 +
.../lucene/spatial/vector/PointVectorStrategy.java | 6 +
.../lucene/spatial3d/PointInGeo3DShapeQuery.java | 8 +
.../search/suggest/document/CompletionWeight.java | 7 -
.../search/suggest/document/ContextQuery.java | 6 +
.../suggest/document/PrefixCompletionQuery.java | 5 +
.../suggest/document/RegexCompletionQuery.java | 6 +
.../org/apache/lucene/search/AssertingQuery.java | 5 +
.../lucene/search/BlockScoreQueryWrapper.java | 12 +-
.../java/org/apache/lucene/search/QueryUtils.java | 3 +
.../lucene/search/RandomApproximationQuery.java | 7 +-
.../lucene/search/ShardSearchingTestBase.java | 5 +-
.../lucene/search/spans/AssertingSpanQuery.java | 12 +-
.../lucene/search/spans/AssertingSpanWeight.java | 7 -
.../java/org/apache/solr/ltr/LTRScoringQuery.java | 15 +-
.../java/org/apache/solr/ltr/feature/Feature.java | 13 +-
.../solr/ltr/feature/OriginalScoreFeature.java | 7 -
.../org/apache/solr/ltr/feature/SolrFeature.java | 9 -
.../solr/legacy/LegacyNumericRangeQuery.java | 8 +-
.../apache/solr/parser/SolrQueryParserBase.java | 8 +-
.../java/org/apache/solr/query/FilterQuery.java | 5 +
.../java/org/apache/solr/query/SolrRangeQuery.java | 8 +-
.../java/org/apache/solr/schema/LatLonType.java | 7 +
.../apache/solr/search/AbstractReRankQuery.java | 6 +
.../org/apache/solr/search/AnalyticsQuery.java | 8 +-
.../solr/search/CollapsingQParserPlugin.java | 6 +
.../apache/solr/search/ExportQParserPlugin.java | 6 +
.../src/java/org/apache/solr/search/Filter.java | 11 +-
.../solr/search/GraphTermsQParserPlugin.java | 20 +-
.../org/apache/solr/search/HashQParserPlugin.java | 6 +
.../org/apache/solr/search/JoinQParserPlugin.java | 6 +
.../apache/solr/search/SolrConstantScoreQuery.java | 6 +
.../org/apache/solr/search/SolrIndexSearcher.java | 5 +
.../java/org/apache/solr/search/WrappedQuery.java | 10 +-
.../solr/search/join/BlockJoinFacetFilter.java | 6 +
.../org/apache/solr/search/join/GraphQuery.java | 14 +-
.../solr/search/join/ScoreJoinQParserPlugin.java | 6 +
.../apache/solr/search/stats/ExactStatsCache.java | 34 ++-
.../apache/solr/update/DeleteByQueryWrapper.java | 13 +-
.../org/apache/solr/update/SolrIndexSplitter.java | 6 +
.../apache/solr/search/RankQueryTestPlugin.java | 6 +
.../solr/uninverting/TestFieldCacheSortRandom.java | 8 +-
180 files changed, 1835 insertions(+), 913 deletions(-)
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index cf9f100..203dbc8 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -10,6 +10,9 @@ API Changes
* LUCENE-8474: RAMDirectory and associated deprecated classes have been
removed. (Dawid Weiss)
+* LUCENE-3041: The deprecated Weight#extractTerms() method has been
+ removed (Alan Woodward, Simon Willnauer, David Smiley, Luca Cavanna)
+
Bug fixes:
* LUCENE-8663: NRTCachingDirectory.slowFileExists may open a file while
@@ -17,6 +20,16 @@ Bug fixes:
======================= Lucene 8.1.0 =======================
+API Changes
+
+* LUCENE-3041: A query introspection API has been added. Queries should
+ implement a visit() method, taking a QueryVisitor, and either pass the
+ visitor down to any child queries, or call a visitX() or consumeX() method
+ on it. All locations in the code that called Weight.extractTerms()
+ have been changed to use this API, and the extractTerms() method has
+ been deprecated. (Alan Woodward, Simon Willnauer, David Smiley, Luca
+ Cavanna)
+
Bug fixes
* LUCENE-8712: Polygon2D does not detect crossings through segment edges.
diff --git a/lucene/classification/src/java/org/apache/lucene/classification/utils/NearestFuzzyQuery.java b/lucene/classification/src/java/org/apache/lucene/classification/utils/NearestFuzzyQuery.java
index ad15372..3b80de7 100644
--- a/lucene/classification/src/java/org/apache/lucene/classification/utils/NearestFuzzyQuery.java
+++ b/lucene/classification/src/java/org/apache/lucene/classification/utils/NearestFuzzyQuery.java
@@ -39,6 +39,7 @@ import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.FuzzyTermsEnum;
import org.apache.lucene.search.MaxNonCompetitiveBoostAttribute;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.util.AttributeSource;
import org.apache.lucene.util.BytesRef;
@@ -327,4 +328,9 @@ public class NearestFuzzyQuery extends Query {
Objects.equals(fieldVals, other.fieldVals);
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
}
diff --git a/lucene/core/src/java/org/apache/lucene/document/FeatureQuery.java b/lucene/core/src/java/org/apache/lucene/document/FeatureQuery.java
index efc2d00..bc69344 100644
--- a/lucene/core/src/java/org/apache/lucene/document/FeatureQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/document/FeatureQuery.java
@@ -18,14 +18,12 @@ package org.apache.lucene.document;
import java.io.IOException;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.document.FeatureField.FeatureFunction;
import org.apache.lucene.index.ImpactsEnum;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.PostingsEnum;
-import org.apache.lucene.index.Term;
import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.search.DocIdSetIterator;
@@ -33,6 +31,7 @@ import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.ImpactsDISI;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
@@ -90,18 +89,6 @@ final class FeatureQuery extends Query {
}
@Override
- public void extractTerms(Set<Term> terms) {
- if (scoreMode.needsScores() == false) {
- // features are irrelevant to highlighting, skip
- } else {
- // extracting the term here will help get better scoring with
- // distributed term statistics if the saturation function is used
- // and the pivot value is computed automatically
- terms.add(new Term(fieldName, featureName));
- }
- }
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
String desc = "weight(" + getQuery() + " in " + doc + ") [" + function + "]";
@@ -175,6 +162,13 @@ final class FeatureQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(fieldName)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public String toString(String field) {
return "FeatureQuery(field=" + fieldName + ", feature=" + featureName + ", function=" + function + ")";
}
diff --git a/lucene/core/src/java/org/apache/lucene/document/LatLonDocValuesBoxQuery.java b/lucene/core/src/java/org/apache/lucene/document/LatLonDocValuesBoxQuery.java
index f34089ef..180caa5 100644
--- a/lucene/core/src/java/org/apache/lucene/document/LatLonDocValuesBoxQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/document/LatLonDocValuesBoxQuery.java
@@ -27,6 +27,7 @@ import org.apache.lucene.search.ConstantScoreScorer;
import org.apache.lucene.search.ConstantScoreWeight;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TwoPhaseIterator;
@@ -96,6 +97,13 @@ final class LatLonDocValuesBoxQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
return new ConstantScoreWeight(this, boost) {
@Override
diff --git a/lucene/core/src/java/org/apache/lucene/document/LatLonDocValuesDistanceQuery.java b/lucene/core/src/java/org/apache/lucene/document/LatLonDocValuesDistanceQuery.java
index 5fd1924..5ea137b 100644
--- a/lucene/core/src/java/org/apache/lucene/document/LatLonDocValuesDistanceQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/document/LatLonDocValuesDistanceQuery.java
@@ -27,6 +27,7 @@ import org.apache.lucene.search.ConstantScoreScorer;
import org.apache.lucene.search.ConstantScoreWeight;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TwoPhaseIterator;
@@ -55,6 +56,13 @@ final class LatLonDocValuesDistanceQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public String toString(String field) {
StringBuilder sb = new StringBuilder();
if (!this.field.equals(field)) {
diff --git a/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceFeatureQuery.java b/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceFeatureQuery.java
index 3f30dea..3a34cae 100644
--- a/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceFeatureQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceFeatureQuery.java
@@ -18,7 +18,6 @@ package org.apache.lucene.document;
import java.io.IOException;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.geo.GeoEncodingUtils;
import org.apache.lucene.geo.GeoUtils;
@@ -30,11 +29,11 @@ import org.apache.lucene.index.PointValues;
import org.apache.lucene.index.PointValues.IntersectVisitor;
import org.apache.lucene.index.PointValues.Relation;
import org.apache.lucene.index.SortedNumericDocValues;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.ScorerSupplier;
@@ -65,6 +64,13 @@ final class LatLonPointDistanceFeatureQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public final boolean equals(Object o) {
return sameClassAs(o) &&
equalsTo(getClass().cast(o));
@@ -102,9 +108,6 @@ final class LatLonPointDistanceFeatureQuery extends Query {
}
@Override
- public void extractTerms(Set<Term> terms) {}
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
SortedNumericDocValues multiDocValues = DocValues.getSortedNumeric(context.reader(), field);
if (multiDocValues.advanceExact(doc) == false) {
diff --git a/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java b/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java
index ca9ff22..969a133 100644
--- a/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java
@@ -32,6 +32,7 @@ import org.apache.lucene.search.ConstantScoreWeight;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.ScorerSupplier;
@@ -72,6 +73,13 @@ final class LatLonPointDistanceQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
Rectangle box = Rectangle.fromPointDistance(latitude, longitude, radiusMeters);
// create bounding box(es) for the distance range
diff --git a/lucene/core/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java b/lucene/core/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java
index 2e4d98d..e425d16 100644
--- a/lucene/core/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java
@@ -33,6 +33,7 @@ import org.apache.lucene.search.ConstantScoreScorer;
import org.apache.lucene.search.ConstantScoreWeight;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
@@ -76,6 +77,13 @@ final class LatLonPointInPolygonQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
// I don't use RandomAccessWeight here: it's no good to approximate with "match all docs"; this is an inverted structure and should be
diff --git a/lucene/core/src/java/org/apache/lucene/document/LongDistanceFeatureQuery.java b/lucene/core/src/java/org/apache/lucene/document/LongDistanceFeatureQuery.java
index 480cfce..a2b793b 100644
--- a/lucene/core/src/java/org/apache/lucene/document/LongDistanceFeatureQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/document/LongDistanceFeatureQuery.java
@@ -18,7 +18,6 @@ package org.apache.lucene.document;
import java.io.IOException;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.LeafReaderContext;
@@ -27,11 +26,11 @@ import org.apache.lucene.index.PointValues;
import org.apache.lucene.index.PointValues.IntersectVisitor;
import org.apache.lucene.index.PointValues.Relation;
import org.apache.lucene.index.SortedNumericDocValues;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.ScorerSupplier;
@@ -76,6 +75,13 @@ final class LongDistanceFeatureQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public String toString(String field) {
return getClass().getSimpleName() + "(field=" + field + ",origin=" + origin + ",pivotDistance=" + pivotDistance + ")";
}
@@ -90,9 +96,6 @@ final class LongDistanceFeatureQuery extends Query {
}
@Override
- public void extractTerms(Set<Term> terms) {}
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
SortedNumericDocValues multiDocValues = DocValues.getSortedNumeric(context.reader(), field);
if (multiDocValues.advanceExact(doc) == false) {
diff --git a/lucene/core/src/java/org/apache/lucene/document/RangeFieldQuery.java b/lucene/core/src/java/org/apache/lucene/document/RangeFieldQuery.java
index 6b235fe..ac21a43 100644
--- a/lucene/core/src/java/org/apache/lucene/document/RangeFieldQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/document/RangeFieldQuery.java
@@ -31,10 +31,11 @@ import org.apache.lucene.search.ConstantScoreWeight;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
+import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.ScorerSupplier;
import org.apache.lucene.search.Weight;
-import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.util.DocIdSetBuilder;
import org.apache.lucene.util.FutureArrays;
@@ -262,6 +263,13 @@ abstract class RangeFieldQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public final Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
return new ConstantScoreWeight(this, boost) {
diff --git a/lucene/core/src/java/org/apache/lucene/document/SortedNumericDocValuesRangeQuery.java b/lucene/core/src/java/org/apache/lucene/document/SortedNumericDocValuesRangeQuery.java
index 771af5c..60222c3 100644
--- a/lucene/core/src/java/org/apache/lucene/document/SortedNumericDocValuesRangeQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/document/SortedNumericDocValuesRangeQuery.java
@@ -30,6 +30,7 @@ import org.apache.lucene.search.ConstantScoreWeight;
import org.apache.lucene.search.DocValuesFieldExistsQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TwoPhaseIterator;
@@ -68,6 +69,13 @@ abstract class SortedNumericDocValuesRangeQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public String toString(String field) {
StringBuilder b = new StringBuilder();
if (this.field.equals(field) == false) {
diff --git a/lucene/core/src/java/org/apache/lucene/document/SortedSetDocValuesRangeQuery.java b/lucene/core/src/java/org/apache/lucene/document/SortedSetDocValuesRangeQuery.java
index e5d365f..88792ba 100644
--- a/lucene/core/src/java/org/apache/lucene/document/SortedSetDocValuesRangeQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/document/SortedSetDocValuesRangeQuery.java
@@ -30,6 +30,7 @@ import org.apache.lucene.search.ConstantScoreWeight;
import org.apache.lucene.search.DocValuesFieldExistsQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TwoPhaseIterator;
@@ -79,6 +80,13 @@ abstract class SortedSetDocValuesRangeQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public String toString(String field) {
StringBuilder b = new StringBuilder();
if (this.field.equals(field) == false) {
diff --git a/lucene/core/src/java/org/apache/lucene/search/AutomatonQuery.java b/lucene/core/src/java/org/apache/lucene/search/AutomatonQuery.java
index 7fb155d..a4a5344 100644
--- a/lucene/core/src/java/org/apache/lucene/search/AutomatonQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/AutomatonQuery.java
@@ -151,7 +151,14 @@ public class AutomatonQuery extends MultiTermQuery {
buffer.append("}");
return buffer.toString();
}
-
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(getField())) {
+ visitor.visitLeaf(this);
+ }
+ }
+
/** Returns the automaton used to create this query */
public Automaton getAutomaton() {
return automaton;
diff --git a/lucene/core/src/java/org/apache/lucene/search/BlendedTermQuery.java b/lucene/core/src/java/org/apache/lucene/search/BlendedTermQuery.java
index 8f85e25..00ba5a1 100644
--- a/lucene/core/src/java/org/apache/lucene/search/BlendedTermQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/BlendedTermQuery.java
@@ -25,8 +25,8 @@ import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexReaderContext;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.Term;
-import org.apache.lucene.index.TermStates;
import org.apache.lucene.index.TermState;
+import org.apache.lucene.index.TermStates;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.util.ArrayUtil;
import org.apache.lucene.util.InPlaceMergeSorter;
@@ -294,6 +294,15 @@ public final class BlendedTermQuery extends Query {
return rewriteMethod.rewrite(termQueries);
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ Term[] termsToVisit = Arrays.stream(terms).filter(t -> visitor.acceptField(t.field())).toArray(Term[]::new);
+ if (termsToVisit.length > 0) {
+ QueryVisitor v = visitor.getSubVisitor(Occur.SHOULD, this);
+ v.consumeTerms(this, termsToVisit);
+ }
+ }
+
private static TermStates adjustFrequencies(IndexReaderContext readerContext,
TermStates ctx, int artificialDf, long artificialTtf) throws IOException {
List<LeafReaderContext> leaves = readerContext.leaves();
diff --git a/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java b/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java
index f52df9f..87105b0 100644
--- a/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/BooleanQuery.java
@@ -451,6 +451,18 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
return super.rewrite(reader);
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ for (BooleanClause.Occur occur : clauseSets.keySet()) {
+ if (clauseSets.get(occur).size() > 0) {
+ QueryVisitor v = visitor.getSubVisitor(occur, this);
+ for (Query q : clauseSets.get(occur)) {
+ q.visit(v);
+ }
+ }
+ }
+ }
+
/** Prints a user-readable version of this query. */
@Override
public String toString(String field) {
diff --git a/lucene/core/src/java/org/apache/lucene/search/BooleanWeight.java b/lucene/core/src/java/org/apache/lucene/search/BooleanWeight.java
index 6298513..cded651 100644
--- a/lucene/core/src/java/org/apache/lucene/search/BooleanWeight.java
+++ b/lucene/core/src/java/org/apache/lucene/search/BooleanWeight.java
@@ -24,10 +24,8 @@ import java.util.EnumMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.util.Bits;
@@ -57,17 +55,6 @@ final class BooleanWeight extends Weight {
}
@Override
- public void extractTerms(Set<Term> terms) {
- int i = 0;
- for (BooleanClause clause : query) {
- if (clause.isScoring() || (scoreMode.needsScores() == false && clause.isProhibited() == false)) {
- weights.get(i).extractTerms(terms);
- }
- i++;
- }
- }
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
final int minShouldMatch = query.getMinimumNumberShouldMatch();
List<Explanation> subs = new ArrayList<>();
diff --git a/lucene/core/src/java/org/apache/lucene/search/BoostQuery.java b/lucene/core/src/java/org/apache/lucene/search/BoostQuery.java
index 4e4649c..5f04363 100644
--- a/lucene/core/src/java/org/apache/lucene/search/BoostQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/BoostQuery.java
@@ -105,6 +105,11 @@ public final class BoostQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ query.visit(visitor.getSubVisitor(BooleanClause.Occur.MUST, this));
+ }
+
+ @Override
public String toString(String field) {
StringBuilder builder = new StringBuilder();
builder.append("(");
diff --git a/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java b/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java
index 5c9ed19..9ad256d 100644
--- a/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/ConstantScoreQuery.java
@@ -64,6 +64,11 @@ public final class ConstantScoreQuery extends Query {
return super.rewrite(reader);
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ query.visit(visitor.getSubVisitor(BooleanClause.Occur.FILTER, this));
+ }
+
/** We return this as our {@link BulkScorer} so that if the CSQ
* wraps a query with its own optimized top-level
* scorer (e.g. BooleanScorer) we can use that
diff --git a/lucene/core/src/java/org/apache/lucene/search/ConstantScoreWeight.java b/lucene/core/src/java/org/apache/lucene/search/ConstantScoreWeight.java
index 671ec71..7ee4cce 100644
--- a/lucene/core/src/java/org/apache/lucene/search/ConstantScoreWeight.java
+++ b/lucene/core/src/java/org/apache/lucene/search/ConstantScoreWeight.java
@@ -18,10 +18,8 @@ package org.apache.lucene.search;
import java.io.IOException;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
/**
* A Weight that has a constant score equal to the boost of the wrapped query.
@@ -39,13 +37,6 @@ public abstract class ConstantScoreWeight extends Weight {
this.score = score;
}
- @Override
- public void extractTerms(Set<Term> terms) {
- // most constant-score queries don't wrap index terms
- // eg. geo filters, doc values queries, ...
- // override if your constant-score query does wrap terms
- }
-
/** Return the score produced by this {@link Weight}. */
protected final float score() {
return score;
diff --git a/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java b/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java
index 43b42b5..4ffd326 100644
--- a/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java
@@ -24,11 +24,9 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
-import java.util.Set;
-import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.Term;
+import org.apache.lucene.index.LeafReaderContext;
/**
* A query that generates the union of documents produced by its subqueries, and that scores each document with the maximum
@@ -112,13 +110,6 @@ public final class DisjunctionMaxQuery extends Query implements Iterable<Query>
}
@Override
- public void extractTerms(Set<Term> terms) {
- for (Weight weight : weights) {
- weight.extractTerms(terms);
- }
- }
-
- @Override
public Matches matches(LeafReaderContext context, int doc) throws IOException {
List<Matches> mis = new ArrayList<>();
for (Weight weight : weights) {
@@ -237,6 +228,14 @@ public final class DisjunctionMaxQuery extends Query implements Iterable<Query>
return super.rewrite(reader);
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ QueryVisitor v = visitor.getSubVisitor(BooleanClause.Occur.SHOULD, this);
+ for (Query q : disjuncts) {
+ q.visit(v);
+ }
+ }
+
/** Prettyprint us.
* @param field the field to which we are applied
* @return a string that shows what we do, of the form "(disjunct1 | disjunct2 | ... | disjunctn)^boost"
diff --git a/lucene/core/src/java/org/apache/lucene/search/DocValuesFieldExistsQuery.java b/lucene/core/src/java/org/apache/lucene/search/DocValuesFieldExistsQuery.java
index 4b9c97d..bca34c2 100644
--- a/lucene/core/src/java/org/apache/lucene/search/DocValuesFieldExistsQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/DocValuesFieldExistsQuery.java
@@ -60,6 +60,13 @@ public final class DocValuesFieldExistsQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) {
return new ConstantScoreWeight(this, boost) {
@Override
diff --git a/lucene/core/src/java/org/apache/lucene/search/DocValuesRewriteMethod.java b/lucene/core/src/java/org/apache/lucene/search/DocValuesRewriteMethod.java
index d328b42..b1a7ef7 100644
--- a/lucene/core/src/java/org/apache/lucene/search/DocValuesRewriteMethod.java
+++ b/lucene/core/src/java/org/apache/lucene/search/DocValuesRewriteMethod.java
@@ -70,6 +70,13 @@ public final class DocValuesRewriteMethod extends MultiTermQuery.RewriteMethod {
/** Returns the field name for this query */
public final String getField() { return query.getField(); }
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(query.getField())) {
+ visitor.visitLeaf(this);
+ }
+ }
@Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
diff --git a/lucene/core/src/java/org/apache/lucene/search/FilterWeight.java b/lucene/core/src/java/org/apache/lucene/search/FilterWeight.java
index 8a2b57b..5292e78 100644
--- a/lucene/core/src/java/org/apache/lucene/search/FilterWeight.java
+++ b/lucene/core/src/java/org/apache/lucene/search/FilterWeight.java
@@ -17,10 +17,8 @@
package org.apache.lucene.search;
import java.io.IOException;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
/**
* A {@code FilterWeight} contains another {@code Weight} and implements
@@ -61,11 +59,6 @@ public abstract class FilterWeight extends Weight {
}
@Override
- public void extractTerms(Set<Term> terms) {
- in.extractTerms(terms);
- }
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
return in.explain(context, doc);
}
diff --git a/lucene/core/src/java/org/apache/lucene/search/FuzzyQuery.java b/lucene/core/src/java/org/apache/lucene/search/FuzzyQuery.java
index 3c1eacd..344f921 100644
--- a/lucene/core/src/java/org/apache/lucene/search/FuzzyQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/FuzzyQuery.java
@@ -24,6 +24,7 @@ import org.apache.lucene.index.Term;
import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.util.AttributeSource;
+import org.apache.lucene.util.automaton.Automaton;
import org.apache.lucene.util.automaton.LevenshteinAutomata;
/** Implements the fuzzy search query. The similarity measurement
@@ -146,6 +147,21 @@ public class FuzzyQuery extends MultiTermQuery {
return transpositions;
}
+ /**
+ * Expert: Constructs an equivalent Automaton accepting terms matched by this query
+ */
+ public Automaton toAutomaton() {
+ return FuzzyTermsEnum.buildAutomaton(term.text(), prefixLength, transpositions, maxEdits);
+ }
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ // TODO find some way of consuming Automata
+ if (visitor.acceptField(term.field())) {
+ visitor.visitLeaf(this);
+ }
+ }
+
@Override
protected TermsEnum getTermsEnum(Terms terms, AttributeSource atts) throws IOException {
if (maxEdits == 0 || prefixLength >= term.text().length()) { // can only match if it's exact
@@ -153,7 +169,7 @@ public class FuzzyQuery extends MultiTermQuery {
}
return new FuzzyTermsEnum(terms, atts, getTerm(), maxEdits, prefixLength, transpositions);
}
-
+
/**
* Returns the pattern term.
*/
@@ -173,7 +189,7 @@ public class FuzzyQuery extends MultiTermQuery {
buffer.append(Integer.toString(maxEdits));
return buffer.toString();
}
-
+
@Override
public int hashCode() {
final int prime = 31;
diff --git a/lucene/core/src/java/org/apache/lucene/search/FuzzyTermsEnum.java b/lucene/core/src/java/org/apache/lucene/search/FuzzyTermsEnum.java
index a6d56e7..4759220 100644
--- a/lucene/core/src/java/org/apache/lucene/search/FuzzyTermsEnum.java
+++ b/lucene/core/src/java/org/apache/lucene/search/FuzzyTermsEnum.java
@@ -17,6 +17,9 @@
package org.apache.lucene.search;
+import java.io.IOException;
+import java.util.Arrays;
+
import org.apache.lucene.index.BaseTermsEnum;
import org.apache.lucene.index.ImpactsEnum;
import org.apache.lucene.index.PostingsEnum;
@@ -35,9 +38,6 @@ import org.apache.lucene.util.automaton.Automaton;
import org.apache.lucene.util.automaton.CompiledAutomaton;
import org.apache.lucene.util.automaton.LevenshteinAutomata;
-import java.io.IOException;
-import java.util.Arrays;
-
/** Subclass of TermsEnum for enumerating all terms that are similar
* to the specified filter term.
*
@@ -111,11 +111,7 @@ public final class FuzzyTermsEnum extends BaseTermsEnum {
this.term = term;
// convert the string into a utf32 int[] representation for fast comparisons
- final String utf16 = term.text();
- this.termText = new int[utf16.codePointCount(0, utf16.length())];
- for (int cp, i = 0, j = 0; i < utf16.length(); i += Character.charCount(cp)) {
- termText[j++] = cp = utf16.codePointAt(i);
- }
+ this.termText = stringToUTF32(term.text());
this.termLength = termText.length;
this.dfaAtt = atts.addAttribute(LevenshteinAutomataAttribute.class);
@@ -133,16 +129,10 @@ public final class FuzzyTermsEnum extends BaseTermsEnum {
CompiledAutomaton[] prevAutomata = dfaAtt.automata();
if (prevAutomata == null) {
prevAutomata = new CompiledAutomaton[maxEdits+1];
-
- LevenshteinAutomata builder =
- new LevenshteinAutomata(UnicodeUtil.newString(termText, realPrefixLength, termText.length - realPrefixLength), transpositions);
-
- String prefix = UnicodeUtil.newString(termText, 0, realPrefixLength);
+ Automaton[] automata = buildAutomata(termText, prefixLength, transpositions, maxEdits);
for (int i = 0; i <= maxEdits; i++) {
- Automaton a = builder.toAutomaton(i, prefix);
- prevAutomata[i] = new CompiledAutomaton(a, true, false);
+ prevAutomata[i] = new CompiledAutomaton(automata[i], true, false);
}
-
// first segment computes the automata, and we share with subsequent segments via this Attribute:
dfaAtt.setAutomata(prevAutomata);
}
@@ -152,6 +142,46 @@ public final class FuzzyTermsEnum extends BaseTermsEnum {
bottomTerm = maxBoostAtt.getCompetitiveTerm();
bottomChanged(null);
}
+
+ /**
+ * Builds a binary Automaton to match a fuzzy term
+ * @param text the term to match
+ * @param prefixLength length of a required common prefix
+ * @param transpositions {@code true} if transpositions should count as a single edit
+ * @param maxEdits the maximum edit distance of matching terms
+ */
+ public static Automaton buildAutomaton(String text, int prefixLength, boolean transpositions, int maxEdits) {
+ int[] termText = stringToUTF32(text);
+ Automaton[] automata = buildAutomata(termText, prefixLength, transpositions, maxEdits);
+ return automata[automata.length - 1];
+ }
+
+ private static int[] stringToUTF32(String text) {
+ int[] termText = new int[text.codePointCount(0, text.length())];
+ for (int cp, i = 0, j = 0; i < text.length(); i += Character.charCount(cp)) {
+ termText[j++] = cp = text.codePointAt(i);
+ }
+ return termText;
+ }
+
+ private static Automaton[] buildAutomata(int[] termText, int prefixLength, boolean transpositions, int maxEdits) {
+ if (maxEdits < 0 || maxEdits > LevenshteinAutomata.MAXIMUM_SUPPORTED_DISTANCE) {
+ throw new IllegalArgumentException("max edits must be 0.." + LevenshteinAutomata.MAXIMUM_SUPPORTED_DISTANCE + ", inclusive; got: " + maxEdits);
+ }
+ if (prefixLength < 0) {
+ throw new IllegalArgumentException("prefixLength cannot be less than 0");
+ }
+ Automaton[] automata = new Automaton[maxEdits + 1];
+ int termLength = termText.length;
+ prefixLength = Math.min(prefixLength, termLength);
+ String suffix = UnicodeUtil.newString(termText, prefixLength, termText.length - prefixLength);
+ LevenshteinAutomata builder = new LevenshteinAutomata(suffix, transpositions);
+ String prefix = UnicodeUtil.newString(termText, 0, prefixLength);
+ for (int i = 0; i <= maxEdits; i++) {
+ automata[i] = builder.toAutomaton(i, prefix);
+ }
+ return automata;
+ }
/**
* return an automata-based enum for matching up to editDistance from
diff --git a/lucene/core/src/java/org/apache/lucene/search/IndexOrDocValuesQuery.java b/lucene/core/src/java/org/apache/lucene/search/IndexOrDocValuesQuery.java
index d69421e..a3a3a22 100644
--- a/lucene/core/src/java/org/apache/lucene/search/IndexOrDocValuesQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/IndexOrDocValuesQuery.java
@@ -17,13 +17,11 @@
package org.apache.lucene.search;
import java.io.IOException;
-import java.util.Set;
import org.apache.lucene.document.LongPoint;
import org.apache.lucene.document.SortedNumericDocValuesField;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
/**
* A query that uses either an index structure (points or terms) or doc values
@@ -110,16 +108,18 @@ public final class IndexOrDocValuesQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ QueryVisitor v = visitor.getSubVisitor(BooleanClause.Occur.MUST, this);
+ indexQuery.visit(v);
+ dvQuery.visit(v);
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
final Weight indexWeight = indexQuery.createWeight(searcher, scoreMode, boost);
final Weight dvWeight = dvQuery.createWeight(searcher, scoreMode, boost);
return new Weight(this) {
@Override
- public void extractTerms(Set<Term> terms) {
- indexWeight.extractTerms(terms);
- }
-
- @Override
public Matches matches(LeafReaderContext context, int doc) throws IOException {
// We need to check a single doc, so the dv query should perform better
return dvWeight.matches(context, doc);
diff --git a/lucene/core/src/java/org/apache/lucene/search/LRUQueryCache.java b/lucene/core/src/java/org/apache/lucene/search/LRUQueryCache.java
index c2448ed..ae62c57 100644
--- a/lucene/core/src/java/org/apache/lucene/search/LRUQueryCache.java
+++ b/lucene/core/src/java/org/apache/lucene/search/LRUQueryCache.java
@@ -36,7 +36,6 @@ import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexReaderContext;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.ReaderUtil;
-import org.apache.lucene.index.Term;
import org.apache.lucene.index.TieredMergePolicy;
import org.apache.lucene.util.Accountable;
import org.apache.lucene.util.Accountables;
@@ -674,11 +673,6 @@ public class LRUQueryCache implements QueryCache, Accountable {
}
@Override
- public void extractTerms(Set<Term> terms) {
- in.extractTerms(terms);
- }
-
- @Override
public Matches matches(LeafReaderContext context, int doc) throws IOException {
return in.matches(context, doc);
}
diff --git a/lucene/core/src/java/org/apache/lucene/search/MatchAllDocsQuery.java b/lucene/core/src/java/org/apache/lucene/search/MatchAllDocsQuery.java
index 80e8d32..ca414c2 100644
--- a/lucene/core/src/java/org/apache/lucene/search/MatchAllDocsQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/MatchAllDocsQuery.java
@@ -89,4 +89,9 @@ public final class MatchAllDocsQuery extends Query {
public int hashCode() {
return classHash();
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
}
diff --git a/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java b/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java
index 525a183..fae20a8 100644
--- a/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/MatchNoDocsQuery.java
@@ -18,10 +18,8 @@ package org.apache.lucene.search;
import java.io.IOException;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
/**
* A query that matches no documents.
@@ -45,10 +43,6 @@ public class MatchNoDocsQuery extends Query {
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
return new Weight(this) {
@Override
- public void extractTerms(Set<Term> terms) {
- }
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
return Explanation.noMatch(reason);
}
@@ -66,6 +60,11 @@ public class MatchNoDocsQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
+ @Override
public String toString(String field) {
return "MatchNoDocsQuery(\"" + reason + "\")";
}
diff --git a/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java b/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
index c8d22ba..4aafa7b 100644
--- a/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
@@ -21,12 +21,10 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexReaderContext;
@@ -204,6 +202,18 @@ public class MultiPhraseQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field) == false) {
+ return;
+ }
+ QueryVisitor v = visitor.getSubVisitor(BooleanClause.Occur.MUST, this);
+ for (Term[] terms : termArrays) {
+ QueryVisitor sv = v.getSubVisitor(BooleanClause.Occur.SHOULD, this);
+ sv.consumeTerms(this, terms);
+ }
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
final Map<Term,TermStates> termStates = new HashMap<>();
return new PhraseWeight(this, field, searcher, scoreMode) {
@@ -298,13 +308,6 @@ public class MultiPhraseQuery extends Query {
}
}
-
- @Override
- public void extractTerms(Set<Term> terms) {
- for (final Term[] arr : termArrays) {
- Collections.addAll(terms, arr);
- }
- }
};
}
diff --git a/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryConstantScoreWrapper.java b/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryConstantScoreWrapper.java
index 9c37211..2d7ac9b 100644
--- a/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryConstantScoreWrapper.java
+++ b/lucene/core/src/java/org/apache/lucene/search/MultiTermQueryConstantScoreWrapper.java
@@ -231,4 +231,11 @@ final class MultiTermQueryConstantScoreWrapper<Q extends MultiTermQuery> extends
};
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(getField())) {
+ query.visit(visitor.getSubVisitor(Occur.FILTER, this));
+ }
+ }
}
diff --git a/lucene/core/src/java/org/apache/lucene/search/NGramPhraseQuery.java b/lucene/core/src/java/org/apache/lucene/search/NGramPhraseQuery.java
index db997d3..3f86afa 100644
--- a/lucene/core/src/java/org/apache/lucene/search/NGramPhraseQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/NGramPhraseQuery.java
@@ -78,6 +78,11 @@ public class NGramPhraseQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ phraseQuery.visit(visitor.getSubVisitor(BooleanClause.Occur.MUST, this));
+ }
+
+ @Override
public boolean equals(Object other) {
return sameClassAs(other) &&
equalsTo(getClass().cast(other));
diff --git a/lucene/core/src/java/org/apache/lucene/search/NormsFieldExistsQuery.java b/lucene/core/src/java/org/apache/lucene/search/NormsFieldExistsQuery.java
index 8c86885..984a9a8 100644
--- a/lucene/core/src/java/org/apache/lucene/search/NormsFieldExistsQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/NormsFieldExistsQuery.java
@@ -62,6 +62,13 @@ public final class NormsFieldExistsQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
return new ConstantScoreWeight(this, boost) {
@Override
diff --git a/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java b/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
index 8f04271..271fed6 100644
--- a/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
@@ -20,9 +20,7 @@ package org.apache.lucene.search;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
-import java.util.Set;
import org.apache.lucene.codecs.lucene50.Lucene50PostingsFormat;
import org.apache.lucene.codecs.lucene50.Lucene50PostingsReader;
@@ -255,6 +253,9 @@ public class PhraseQuery extends Query {
*/
public int getSlop() { return slop; }
+ /** Returns the field this query applies to */
+ public String getField() { return field; }
+
/** Returns the list of terms in this phrase. */
public Term[] getTerms() {
return terms;
@@ -284,6 +285,15 @@ public class PhraseQuery extends Query {
}
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field) == false) {
+ return;
+ }
+ QueryVisitor v = visitor.getSubVisitor(BooleanClause.Occur.MUST, this);
+ v.consumeTerms(this, terms);
+ }
+
static class PostingsAndFreq implements Comparable<PostingsAndFreq> {
final PostingsEnum postings;
final int position;
@@ -460,11 +470,6 @@ public class PhraseQuery extends Query {
return new SloppyPhraseMatcher(postingsFreqs, slop, totalMatchCost, exposeOffsets);
}
}
-
- @Override
- public void extractTerms(Set<Term> queryTerms) {
- Collections.addAll(queryTerms, terms);
- }
};
}
diff --git a/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java b/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java
index b6d047e..ad9e258 100644
--- a/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java
@@ -106,6 +106,13 @@ public abstract class PointInSetQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public final Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
// We don't use RandomAccessWeight here: it's no good to approximate with "match all docs".
diff --git a/lucene/core/src/java/org/apache/lucene/search/PointRangeQuery.java b/lucene/core/src/java/org/apache/lucene/search/PointRangeQuery.java
index ca61d51..57c8708 100644
--- a/lucene/core/src/java/org/apache/lucene/search/PointRangeQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/PointRangeQuery.java
@@ -100,6 +100,13 @@ public abstract class PointRangeQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public final Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
// We don't use RandomAccessWeight here: it's no good to approximate with "match all docs".
diff --git a/lucene/core/src/java/org/apache/lucene/search/Query.java b/lucene/core/src/java/org/apache/lucene/search/Query.java
index 54de63f..c594ff0 100644
--- a/lucene/core/src/java/org/apache/lucene/search/Query.java
+++ b/lucene/core/src/java/org/apache/lucene/search/Query.java
@@ -75,6 +75,12 @@ public abstract class Query {
}
/**
+ * Recurse through the query tree, visiting any child queries
+ * @param visitor a QueryVisitor to be called by each query in the tree
+ */
+ public abstract void visit(QueryVisitor visitor);
+
+ /**
* Override and implement query instance equivalence properly in a subclass.
* This is required so that {@link QueryCache} works properly.
*
diff --git a/lucene/core/src/java/org/apache/lucene/search/QueryVisitor.java b/lucene/core/src/java/org/apache/lucene/search/QueryVisitor.java
new file mode 100644
index 0000000..5635f7d
--- /dev/null
+++ b/lucene/core/src/java/org/apache/lucene/search/QueryVisitor.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.search;
+
+import java.util.Arrays;
+import java.util.Set;
+
+import org.apache.lucene.index.Term;
+
+/**
+ * Allows recursion through a query tree
+ *
+ * @see Query#visit(QueryVisitor)
+ */
+public abstract class QueryVisitor {
+
+ /**
+ * Called by leaf queries that match on specific terms
+ *
+ * @param query the leaf query
+ * @param terms the terms the query will match on
+ */
+ public void consumeTerms(Query query, Term... terms) { }
+
+ // TODO it would be nice to have a way to consume 'classes' of Terms from
+ // things like AutomatonQuery
+
+ /**
+ * Called by leaf queries that do not match on terms
+ * @param query the query
+ */
+ public void visitLeaf(Query query) { }
+
+ /**
+ * Whether or not terms from this field are of interest to the visitor
+ *
+ * Implement this to avoid collecting terms from heavy queries such as {@link TermInSetQuery}
+ * that are not running on fields of interest
+ */
+ public boolean acceptField(String field) {
+ return true;
+ }
+
+ /**
+ * Pulls a visitor instance for visiting child clauses of a query
+ *
+ * The default implementation returns {@code this}, unless {@code occur} is equal
+ * to {@link BooleanClause.Occur#MUST_NOT} in which case it returns
+ * {@link #EMPTY_VISITOR}
+ *
+ * @param occur the relationship between the parent and its children
+ * @param parent the query visited
+ */
+ public QueryVisitor getSubVisitor(BooleanClause.Occur occur, Query parent) {
+ if (occur == BooleanClause.Occur.MUST_NOT) {
+ return EMPTY_VISITOR;
+ }
+ return this;
+ }
+
+ /**
+ * Builds a {@code QueryVisitor} instance that collects all terms that may match a query
+ * @param termSet a {@code Set} to add collected terms to
+ */
+ public static QueryVisitor termCollector(Set<Term> termSet) {
+ return new QueryVisitor() {
+ @Override
+ public void consumeTerms(Query query, Term... terms) {
+ termSet.addAll(Arrays.asList(terms));
+ }
+ };
+ }
+
+ /**
+ * A QueryVisitor implementation that does nothing
+ */
+ public static final QueryVisitor EMPTY_VISITOR = new QueryVisitor() {};
+
+}
diff --git a/lucene/core/src/java/org/apache/lucene/search/SynonymQuery.java b/lucene/core/src/java/org/apache/lucene/search/SynonymQuery.java
index fc3a5e4..2d053b6 100644
--- a/lucene/core/src/java/org/apache/lucene/search/SynonymQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/SynonymQuery.java
@@ -25,7 +25,6 @@ import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
-import java.util.Set;
import java.util.stream.Collectors;
import org.apache.lucene.index.Impact;
@@ -54,7 +53,9 @@ import org.apache.lucene.util.PriorityQueue;
* term frequencies for the document.
*/
public final class SynonymQuery extends Query {
+
private final TermAndBoost terms[];
+ private final String field;
/**
* A builder for {@link SynonymQuery}.
@@ -102,7 +103,7 @@ public final class SynonymQuery extends Query {
*/
public SynonymQuery build() {
Collections.sort(terms, Comparator.comparing(a -> a.term));
- return new SynonymQuery(terms.toArray(new TermAndBoost[0]));
+ return new SynonymQuery(terms.toArray(new TermAndBoost[0]), field);
}
}
@@ -111,8 +112,9 @@ public final class SynonymQuery extends Query {
* <p>
* The terms must all have the same field.
*/
- private SynonymQuery(TermAndBoost[] terms) {
+ private SynonymQuery(TermAndBoost[] terms, String field) {
this.terms = Objects.requireNonNull(terms);
+ this.field = field;
}
public List<Term> getTerms() {
@@ -165,6 +167,16 @@ public final class SynonymQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field) == false) {
+ return;
+ }
+ QueryVisitor v = visitor.getSubVisitor(BooleanClause.Occur.SHOULD, this);
+ Term[] ts = Arrays.stream(terms).map(t -> t.term).toArray(Term[]::new);
+ v.consumeTerms(this, ts);
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
if (scoreMode.needsScores()) {
return new SynonymWeight(this, searcher, scoreMode, boost);
@@ -210,13 +222,6 @@ public final class SynonymQuery extends Query {
}
@Override
- public void extractTerms(Set<Term> terms) {
- for (TermAndBoost term : SynonymQuery.this.terms) {
- terms.add(term.term);
- }
- }
-
- @Override
public Matches matches(LeafReaderContext context, int doc) throws IOException {
String field = terms[0].term.field();
Terms indexTerms = context.reader().terms(field);
diff --git a/lucene/core/src/java/org/apache/lucene/search/TermInSetQuery.java b/lucene/core/src/java/org/apache/lucene/search/TermInSetQuery.java
index 814bea2..35298a7 100644
--- a/lucene/core/src/java/org/apache/lucene/search/TermInSetQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/TermInSetQuery.java
@@ -23,7 +23,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
-import java.util.Set;
import java.util.SortedSet;
import org.apache.lucene.index.IndexReader;
@@ -33,8 +32,8 @@ import org.apache.lucene.index.PostingsEnum;
import org.apache.lucene.index.PrefixCodedTerms;
import org.apache.lucene.index.PrefixCodedTerms.TermIterator;
import org.apache.lucene.index.Term;
-import org.apache.lucene.index.TermStates;
import org.apache.lucene.index.TermState;
+import org.apache.lucene.index.TermStates;
import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.search.BooleanClause.Occur;
@@ -123,6 +122,20 @@ public class TermInSetQuery extends Query implements Accountable {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field) == false) {
+ return;
+ }
+ QueryVisitor v = visitor.getSubVisitor(Occur.SHOULD, this);
+ List<Term> terms = new ArrayList<>();
+ TermIterator iterator = termData.iterator();
+ for (BytesRef term = iterator.next(); term != null; term = iterator.next()) {
+ terms.add(new Term(field, BytesRef.deepCopyOf(term)));
+ }
+ v.consumeTerms(this, terms.toArray(new Term[0]));
+ }
+
+ @Override
public boolean equals(Object other) {
return sameClassAs(other) &&
equalsTo(getClass().cast(other));
@@ -213,14 +226,6 @@ public class TermInSetQuery extends Query implements Accountable {
return new ConstantScoreWeight(this, boost) {
@Override
- public void extractTerms(Set<Term> terms) {
- // no-op
- // This query is for abuse cases when the number of terms is too high to
- // run efficiently as a BooleanQuery. So likewise we hide its terms in
- // order to protect highlighters
- }
-
- @Override
public Matches matches(LeafReaderContext context, int doc) throws IOException {
Terms terms = context.reader().terms(field);
if (terms == null || terms.hasPositions() == false) {
diff --git a/lucene/core/src/java/org/apache/lucene/search/TermQuery.java b/lucene/core/src/java/org/apache/lucene/search/TermQuery.java
index 1eebbce..945c1b3 100644
--- a/lucene/core/src/java/org/apache/lucene/search/TermQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/TermQuery.java
@@ -19,7 +19,6 @@ package org.apache.lucene.search;
import java.io.IOException;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.IndexReaderContext;
import org.apache.lucene.index.LeafReader;
@@ -76,11 +75,6 @@ public class TermQuery extends Query {
}
@Override
- public void extractTerms(Set<Term> terms) {
- terms.add(getTerm());
- }
-
- @Override
public Matches matches(LeafReaderContext context, int doc) throws IOException {
TermsEnum te = getTermsEnum(context);
if (te == null) {
@@ -205,6 +199,13 @@ public class TermQuery extends Query {
return new TermWeight(searcher, scoreMode, boost, termState);
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(term.field())) {
+ visitor.consumeTerms(this, term);
+ }
+ }
+
/** Prints a user-readable version of this query. */
@Override
public String toString(String field) {
diff --git a/lucene/core/src/java/org/apache/lucene/search/Weight.java b/lucene/core/src/java/org/apache/lucene/search/Weight.java
index d2fac4c..2f86f4f 100644
--- a/lucene/core/src/java/org/apache/lucene/search/Weight.java
+++ b/lucene/core/src/java/org/apache/lucene/search/Weight.java
@@ -18,12 +18,10 @@ package org.apache.lucene.search;
import java.io.IOException;
-import java.util.Set;
import org.apache.lucene.index.IndexReaderContext;
import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.util.Bits;
/**
@@ -62,14 +60,6 @@ public abstract class Weight implements SegmentCacheable {
}
/**
- * Expert: adds all terms occurring in this query to the terms set. If the
- * {@link Weight} was created with {@code needsScores == true} then this
- * method will only extract terms which are used for scoring, otherwise it
- * will extract all terms which are used for matching.
- */
- public abstract void extractTerms(Set<Term> terms);
-
- /**
* Returns {@link Matches} for a specific document, or {@code null} if the document
* does not match the parent query
*
diff --git a/lucene/core/src/java/org/apache/lucene/search/package-info.java b/lucene/core/src/java/org/apache/lucene/search/package-info.java
index 8120840..fdcd6d6 100644
--- a/lucene/core/src/java/org/apache/lucene/search/package-info.java
+++ b/lucene/core/src/java/org/apache/lucene/search/package-info.java
@@ -398,12 +398,6 @@
* {@link org.apache.lucene.search.similarities.Similarity.SimScorer#explain(Explanation, long) SimScorer#explain(Explanation freq, long norm)}.
* </li>
* <li>
- * {@link org.apache.lucene.search.Weight#extractTerms(java.util.Set) extractTerms(Set<Term> terms)} — Extract terms that
- * this query operates on. This is typically used to support distributed search: knowing the terms that a query operates on helps
- * merge index statistics of these terms so that scores are computed over a subset of the data like they would if all documents
- * were in the same index.
- * </li>
- * <li>
* {@link org.apache.lucene.search.Weight#matches matches(LeafReaderContext context, int doc)} — Give information about positions
* and offsets of matches. This is typically useful to implement highlighting.
* </li>
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/FieldMaskingSpanQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/FieldMaskingSpanQuery.java
index 4a4c4fb..118fc06 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/FieldMaskingSpanQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/FieldMaskingSpanQuery.java
@@ -17,14 +17,16 @@
package org.apache.lucene.search.spans;
+import java.io.IOException;
+import java.util.Objects;
+
import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
-import java.io.IOException;
-import java.util.Objects;
-
/**
* <p>Wrapper to allow {@link SpanQuery} objects participate in composite
* single-field SpanQueries by 'lying' about their search field. That is,
@@ -105,6 +107,13 @@ public final class FieldMaskingSpanQuery extends SpanQuery {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ maskedQuery.visit(visitor.getSubVisitor(BooleanClause.Occur.MUST, this));
+ }
+ }
+
+ @Override
public String toString(String field) {
StringBuilder buffer = new StringBuilder();
buffer.append("mask(");
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanBoostQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanBoostQuery.java
index 9556959..fec5792 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanBoostQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanBoostQuery.java
@@ -21,9 +21,11 @@ import java.io.IOException;
import java.util.Objects;
import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
/**
@@ -94,6 +96,13 @@ public final class SpanBoostQuery extends SpanQuery {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(getField())) {
+ query.visit(visitor.getSubVisitor(BooleanClause.Occur.MUST, this));
+ }
+ }
+
+ @Override
public String toString(String field) {
StringBuilder builder = new StringBuilder();
builder.append("(");
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanContainQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanContainQuery.java
index 23c1e2b..2df1f0b 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanContainQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanContainQuery.java
@@ -17,18 +17,19 @@
package org.apache.lucene.search.spans;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Objects;
+
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermStates;
+import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
+import org.apache.lucene.search.QueryVisitor;
abstract class SpanContainQuery extends SpanQuery implements Cloneable {
@@ -68,15 +69,6 @@ abstract class SpanContainQuery extends SpanQuery implements Cloneable {
this.littleWeight = littleWeight;
}
- /**
- * Extract terms from both <code>big</code> and <code>little</code>.
- */
- @Override
- public void extractTerms(Set<Term> terms) {
- bigWeight.extractTerms(terms);
- littleWeight.extractTerms(terms);
- }
-
ArrayList<Spans> prepareConjunction(final LeafReaderContext context, Postings postings) throws IOException {
Spans bigSpans = bigWeight.getSpans(context, postings);
if (bigSpans == null) {
@@ -129,6 +121,15 @@ abstract class SpanContainQuery extends SpanQuery implements Cloneable {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(getField())) {
+ QueryVisitor v = visitor.getSubVisitor(BooleanClause.Occur.MUST, this);
+ big.visit(v);
+ little.visit(v);
+ }
+ }
+
+ @Override
public boolean equals(Object other) {
return sameClassAs(other) &&
equalsTo(getClass().cast(other));
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java
index 088e730..4f692ae 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java
@@ -29,6 +29,7 @@ import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.ScoringRewrite;
import org.apache.lucene.search.TopTermsRewrite;
@@ -121,7 +122,14 @@ public class SpanMultiTermQueryWrapper<Q extends MultiTermQuery> extends SpanQue
public Query rewrite(IndexReader reader) throws IOException {
return rewriteMethod.rewrite(reader, query);
}
-
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(query.getField())) {
+ query.visit(visitor.getSubVisitor(Occur.MUST, this));
+ }
+ }
+
@Override
public int hashCode() {
return classHash() * 31 + query.hashCode();
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanNearQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanNearQuery.java
index 17b9e51..2f219bf 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanNearQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanNearQuery.java
@@ -24,15 +24,16 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermStates;
import org.apache.lucene.index.Terms;
+import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Weight;
@@ -226,13 +227,6 @@ public class SpanNearQuery extends SpanQuery implements Cloneable {
}
@Override
- public void extractTerms(Set<Term> terms) {
- for (SpanWeight w : subWeights) {
- w.extractTerms(terms);
- }
- }
-
- @Override
public boolean isCacheable(LeafReaderContext ctx) {
for (Weight w : subWeights) {
if (w.isCacheable(ctx) == false)
@@ -266,6 +260,17 @@ public class SpanNearQuery extends SpanQuery implements Cloneable {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(getField()) == false) {
+ return;
+ }
+ QueryVisitor v = visitor.getSubVisitor(BooleanClause.Occur.MUST, this);
+ for (SpanQuery clause : clauses) {
+ clause.visit(v);
+ }
+ }
+
+ @Override
public boolean equals(Object other) {
return sameClassAs(other) &&
equalsTo(getClass().cast(other));
@@ -302,6 +307,11 @@ public class SpanNearQuery extends SpanQuery implements Cloneable {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
+ @Override
public String toString(String field) {
return "SpanGap(" + field + ":" + width + ")";
}
@@ -328,11 +338,6 @@ public class SpanNearQuery extends SpanQuery implements Cloneable {
}
@Override
- public void extractTerms(Set<Term> terms) {
-
- }
-
- @Override
public boolean isCacheable(LeafReaderContext ctx) {
return true;
}
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java
index 6c56df3..5d998fe 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java
@@ -20,15 +20,16 @@ package org.apache.lucene.search.spans;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermStates;
+import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.TwoPhaseIterator;
@@ -189,11 +190,6 @@ public final class SpanNotQuery extends SpanQuery {
}
@Override
- public void extractTerms(Set<Term> terms) {
- includeWeight.extractTerms(terms);
- }
-
- @Override
public boolean isCacheable(LeafReaderContext ctx) {
return includeWeight.isCacheable(ctx) && excludeWeight.isCacheable(ctx);
}
@@ -209,7 +205,16 @@ public final class SpanNotQuery extends SpanQuery {
}
return super.rewrite(reader);
}
- /** Returns true iff <code>o</code> is equal to this. */
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(getField())) {
+ include.visit(visitor.getSubVisitor(BooleanClause.Occur.MUST, this));
+ exclude.visit(visitor.getSubVisitor(BooleanClause.Occur.MUST_NOT, this));
+ }
+ }
+
+ /** Returns true iff <code>o</code> is equal to this. */
@Override
public boolean equals(Object other) {
return sameClassAs(other) &&
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java
index 849edaa..5f589e1 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java
@@ -22,17 +22,18 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermStates;
+import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.DisiPriorityQueue;
import org.apache.lucene.search.DisiWrapper;
import org.apache.lucene.search.DisjunctionDISIApproximation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.TwoPhaseIterator;
import org.apache.lucene.search.Weight;
@@ -89,6 +90,17 @@ public final class SpanOrQuery extends SpanQuery {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(getField()) == false) {
+ return;
+ }
+ QueryVisitor v = visitor.getSubVisitor(BooleanClause.Occur.SHOULD, this);
+ for (SpanQuery q : clauses) {
+ q.visit(v);
+ }
+ }
+
+ @Override
public String toString(String field) {
StringBuilder buffer = new StringBuilder();
buffer.append("spanOr([");
@@ -134,13 +146,6 @@ public final class SpanOrQuery extends SpanQuery {
}
@Override
- public void extractTerms(Set<Term> terms) {
- for (final SpanWeight w: subWeights) {
- w.extractTerms(terms);
- }
- }
-
- @Override
public boolean isCacheable(LeafReaderContext ctx) {
for (Weight w : subWeights) {
if (w.isCacheable(ctx) == false)
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java
index 099b627..3e40c64 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java
@@ -20,14 +20,15 @@ package org.apache.lucene.search.spans;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermStates;
+import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.spans.FilterSpans.AcceptStatus;
@@ -83,11 +84,6 @@ public abstract class SpanPositionCheckQuery extends SpanQuery implements Clonea
}
@Override
- public void extractTerms(Set<Term> terms) {
- matchWeight.extractTerms(terms);
- }
-
- @Override
public boolean isCacheable(LeafReaderContext ctx) {
return matchWeight.isCacheable(ctx);
}
@@ -126,6 +122,13 @@ public abstract class SpanPositionCheckQuery extends SpanQuery implements Clonea
return super.rewrite(reader);
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(getField())) {
+ match.visit(visitor.getSubVisitor(BooleanClause.Occur.MUST, this));
+ }
+ }
+
/** Returns true iff <code>other</code> is equal to this. */
@Override
public boolean equals(Object other) {
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java
index 42e73f2..c86e7b7 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java
@@ -21,18 +21,18 @@ import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.IndexReaderContext;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.PostingsEnum;
import org.apache.lucene.index.ReaderUtil;
import org.apache.lucene.index.Term;
-import org.apache.lucene.index.TermStates;
import org.apache.lucene.index.TermState;
+import org.apache.lucene.index.TermStates;
import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
/** Matches spans containing a term.
@@ -84,6 +84,13 @@ public class SpanTermQuery extends SpanQuery {
return new SpanTermWeight(context, searcher, scoreMode.needsScores() ? Collections.singletonMap(term, context) : null, boost);
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(term.field())) {
+ visitor.consumeTerms(this, term);
+ }
+ }
+
public class SpanTermWeight extends SpanWeight {
final TermStates termStates;
@@ -95,11 +102,6 @@ public class SpanTermQuery extends SpanQuery {
}
@Override
- public void extractTerms(Set<Term> terms) {
- terms.add(term);
- }
-
- @Override
public boolean isCacheable(LeafReaderContext ctx) {
return true;
}
diff --git a/lucene/core/src/test/org/apache/lucene/document/TestFeatureField.java b/lucene/core/src/test/org/apache/lucene/document/TestFeatureField.java
index 6a0a335..79534c8 100644
--- a/lucene/core/src/test/org/apache/lucene/document/TestFeatureField.java
+++ b/lucene/core/src/test/org/apache/lucene/document/TestFeatureField.java
@@ -17,15 +17,10 @@
package org.apache.lucene.document;
import java.io.IOException;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.DirectoryReader;
-import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.MultiReader;
import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause.Occur;
@@ -272,27 +267,6 @@ public class TestFeatureField extends LuceneTestCase {
dir.close();
}
- public void testExtractTerms() throws IOException {
- IndexReader reader = new MultiReader();
- IndexSearcher searcher = newSearcher(reader);
- Query query = FeatureField.newLogQuery("field", "term", 2f, 42);
-
- Weight weight = searcher.createWeight(query, ScoreMode.COMPLETE_NO_SCORES, 1f);
- Set<Term> terms = new HashSet<>();
- weight.extractTerms(terms);
- assertEquals(Collections.emptySet(), terms);
-
- terms = new HashSet<>();
- weight = searcher.createWeight(query, ScoreMode.COMPLETE, 1f);
- weight.extractTerms(terms);
- assertEquals(Collections.singleton(new Term("field", "term")), terms);
-
- terms = new HashSet<>();
- weight = searcher.createWeight(query, ScoreMode.TOP_SCORES, 1f);
- weight.extractTerms(terms);
- assertEquals(Collections.singleton(new Term("field", "term")), terms);
- }
-
public void testDemo() throws IOException {
Directory dir = newDirectory();
RandomIndexWriter writer = new RandomIndexWriter(random(), dir, newIndexWriterConfig()
diff --git a/lucene/core/src/test/org/apache/lucene/search/JustCompileSearch.java b/lucene/core/src/test/org/apache/lucene/search/JustCompileSearch.java
index a9d84cf..1029326 100644
--- a/lucene/core/src/test/org/apache/lucene/search/JustCompileSearch.java
+++ b/lucene/core/src/test/org/apache/lucene/search/JustCompileSearch.java
@@ -18,11 +18,9 @@ package org.apache.lucene.search;
import java.io.IOException;
-import java.util.Set;
import org.apache.lucene.index.FieldInvertState;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.util.PriorityQueue;
@@ -154,6 +152,11 @@ final class JustCompileSearch {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ throw new UnsupportedOperationException(UNSUPPORTED_MSG);
+ }
+
+ @Override
public boolean equals(Object obj) {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
}
@@ -243,11 +246,6 @@ final class JustCompileSearch {
}
@Override
- public void extractTerms(Set<Term> terms) {
- throw new UnsupportedOperationException(UNSUPPORTED_MSG);
- }
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
}
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestBoolean2ScorerSupplier.java b/lucene/core/src/test/org/apache/lucene/search/TestBoolean2ScorerSupplier.java
index ea2fd4c..45555f2 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestBoolean2ScorerSupplier.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestBoolean2ScorerSupplier.java
@@ -22,16 +22,13 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.EnumMap;
import java.util.Map;
-import java.util.Set;
+import com.carrotsearch.randomizedtesting.generators.RandomPicks;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.TestUtil;
-import com.carrotsearch.randomizedtesting.generators.RandomPicks;
-
public class TestBoolean2ScorerSupplier extends LuceneTestCase {
private static class FakeWeight extends Weight {
@@ -41,11 +38,6 @@ public class TestBoolean2ScorerSupplier extends LuceneTestCase {
}
@Override
- public void extractTerms(Set<Term> terms) {
-
- }
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
return null;
}
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestBooleanQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestBooleanQuery.java
index 1b5da1b..99f36ac 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestBooleanQuery.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestBooleanQuery.java
@@ -22,14 +22,13 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
+import com.carrotsearch.randomizedtesting.generators.RandomPicks;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.document.Document;
@@ -52,8 +51,6 @@ import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.NamedThreadFactory;
import org.apache.lucene.util.TestUtil;
-import com.carrotsearch.randomizedtesting.generators.RandomPicks;
-
public class TestBooleanQuery extends LuceneTestCase {
public void testEquality() throws Exception {
@@ -754,7 +751,9 @@ public class TestBooleanQuery extends LuceneTestCase {
assertEquals("a +b -c #d", bq.build().toString("field"));
}
- public void testExtractTerms() throws IOException {
+
+
+ public void testQueryVisitor() throws IOException {
Term a = new Term("f", "a");
Term b = new Term("f", "b");
Term c = new Term("f", "c");
@@ -764,15 +763,37 @@ public class TestBooleanQuery extends LuceneTestCase {
bqBuilder.add(new TermQuery(b), Occur.MUST);
bqBuilder.add(new TermQuery(c), Occur.FILTER);
bqBuilder.add(new TermQuery(d), Occur.MUST_NOT);
- IndexSearcher searcher = new IndexSearcher(new MultiReader());
BooleanQuery bq = bqBuilder.build();
- Set<Term> scoringTerms = new HashSet<>();
- searcher.createWeight(searcher.rewrite(bq), ScoreMode.COMPLETE, 1).extractTerms(scoringTerms);
- assertEquals(new HashSet<>(Arrays.asList(a, b)), scoringTerms);
+ bq.visit(new QueryVisitor() {
+
+ Term expected;
- Set<Term> matchingTerms = new HashSet<>();
- searcher.createWeight(searcher.rewrite(bq), ScoreMode.COMPLETE_NO_SCORES, 1).extractTerms(matchingTerms);
- assertEquals(new HashSet<>(Arrays.asList(a, b, c)), matchingTerms);
+ @Override
+ public QueryVisitor getSubVisitor(Occur occur, Query parent) {
+ switch (occur) {
+ case SHOULD:
+ expected = a;
+ break;
+ case MUST:
+ expected = b;
+ break;
+ case FILTER:
+ expected = c;
+ break;
+ case MUST_NOT:
+ expected = d;
+ break;
+ default:
+ throw new IllegalStateException();
+ }
+ return this;
+ }
+
+ @Override
+ public void consumeTerms(Query query, Term... terms) {
+ assertEquals(expected, terms[0]);
+ }
+ });
}
}
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestBooleanScorer.java b/lucene/core/src/test/org/apache/lucene/search/TestBooleanScorer.java
index 75fdd01..9e4351b 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestBooleanScorer.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestBooleanScorer.java
@@ -19,7 +19,6 @@ package org.apache.lucene.search;
import java.io.IOException;
import java.util.Arrays;
-import java.util.Set;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
@@ -80,11 +79,6 @@ public class TestBooleanScorer extends LuceneTestCase {
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
return new Weight(CrazyMustUseBulkScorerQuery.this) {
@Override
- public void extractTerms(Set<Term> terms) {
- throw new UnsupportedOperationException();
- }
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) {
throw new UnsupportedOperationException();
}
@@ -119,6 +113,11 @@ public class TestBooleanScorer extends LuceneTestCase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
+ @Override
public boolean equals(Object obj) {
return this == obj;
}
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestConjunctionDISI.java b/lucene/core/src/test/org/apache/lucene/search/TestConjunctionDISI.java
index a9fd287..e729ed6 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestConjunctionDISI.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestConjunctionDISI.java
@@ -22,10 +22,8 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.util.BitDocIdSet;
import org.apache.lucene.util.FixedBitSet;
import org.apache.lucene.util.LuceneTestCase;
@@ -92,11 +90,6 @@ public class TestConjunctionDISI extends LuceneTestCase {
}
@Override
- public void extractTerms(Set<Term> terms) {
-
- }
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
return null;
}
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java
index 3e15070..eee7bf9 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreQuery.java
@@ -19,15 +19,11 @@ package org.apache.lucene.search;
import java.io.IOException;
import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.MultiReader;
import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause.Occur;
@@ -158,6 +154,11 @@ public class TestConstantScoreQuery extends LuceneTestCase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ in.visit(visitor);
+ }
+
+ @Override
public boolean equals(Object other) {
return sameClassAs(other) &&
in.equals(((QueryWrapper) other).in);
@@ -230,17 +231,4 @@ public class TestConstantScoreQuery extends LuceneTestCase {
dir.close();
}
- public void testExtractTerms() throws Exception {
- final IndexSearcher searcher = newSearcher(new MultiReader());
- final TermQuery termQuery = new TermQuery(new Term("foo", "bar"));
- final Query csq = searcher.rewrite(new ConstantScoreQuery(termQuery));
-
- final Set<Term> scoringTerms = new HashSet<>();
- searcher.createWeight(csq, ScoreMode.COMPLETE, 1).extractTerms(scoringTerms);
- assertEquals(Collections.emptySet(), scoringTerms);
-
- final Set<Term> matchingTerms = new HashSet<>();
- searcher.createWeight(csq, ScoreMode.COMPLETE_NO_SCORES, 1).extractTerms(matchingTerms);
- assertEquals(Collections.singleton(new Term("foo", "bar")), matchingTerms);
- }
}
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestLRUQueryCache.java b/lucene/core/src/test/org/apache/lucene/search/TestLRUQueryCache.java
index 2e3a4f1..6cc4fb9 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestLRUQueryCache.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestLRUQueryCache.java
@@ -29,7 +29,6 @@ import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -379,6 +378,11 @@ public class TestLRUQueryCache extends LuceneTestCase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
+ @Override
public boolean equals(Object other) {
return sameClassAs(other) &&
id == ((DummyQuery) other).id;
@@ -973,6 +977,11 @@ public class TestLRUQueryCache extends LuceneTestCase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
+ @Override
public String toString(String field) {
return "BadQuery";
}
@@ -1305,11 +1314,6 @@ public class TestLRUQueryCache extends LuceneTestCase {
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
return new Weight(this) {
@Override
- public void extractTerms(Set<Term> terms) {
-
- }
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
return null;
}
@@ -1327,6 +1331,11 @@ public class TestLRUQueryCache extends LuceneTestCase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
+ @Override
public String toString(String field) {
return "NoCacheQuery";
}
@@ -1411,6 +1420,11 @@ public class TestLRUQueryCache extends LuceneTestCase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
+ @Override
public boolean equals(Object other) {
return sameClassAs(other);
}
@@ -1494,6 +1508,11 @@ public class TestLRUQueryCache extends LuceneTestCase {
};
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+
+ }
}
public void testDocValuesUpdatesDontBreakCache() throws IOException {
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestMaxScoreSumPropagator.java b/lucene/core/src/test/org/apache/lucene/search/TestMaxScoreSumPropagator.java
index 96a34a5..9da8d1d 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestMaxScoreSumPropagator.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestMaxScoreSumPropagator.java
@@ -22,10 +22,8 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.TestUtil;
@@ -40,11 +38,6 @@ public class TestMaxScoreSumPropagator extends LuceneTestCase {
}
@Override
- public void extractTerms(Set<Term> terms) {
-
- }
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
return null;
}
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestMultiTermQueryRewrites.java b/lucene/core/src/test/org/apache/lucene/search/TestMultiTermQueryRewrites.java
index 44f8d8b..e24e62b 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestMultiTermQueryRewrites.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestMultiTermQueryRewrites.java
@@ -183,6 +183,11 @@ public class TestMultiTermQueryRewrites extends LuceneTestCase {
public String toString(String field) {
return "dummy";
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+
+ }
};
mtq.setRewriteMethod(method);
final Query q1 = searcher.rewrite(mtq);
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestNeedsScores.java b/lucene/core/src/test/org/apache/lucene/search/TestNeedsScores.java
index 03f78ef..3cdbb95 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestNeedsScores.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestNeedsScores.java
@@ -122,6 +122,11 @@ public class TestNeedsScores extends LuceneTestCase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ in.visit(visitor);
+ }
+
+ @Override
public int hashCode() {
final int prime = 31;
int result = classHash();
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestPrefixRandom.java b/lucene/core/src/test/org/apache/lucene/search/TestPrefixRandom.java
index f332a36..8180379 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestPrefixRandom.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestPrefixRandom.java
@@ -109,6 +109,11 @@ public class TestPrefixRandom extends LuceneTestCase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
+ @Override
public boolean equals(Object obj) {
if (super.equals(obj) == false) {
return false;
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestQueryRescorer.java b/lucene/core/src/test/org/apache/lucene/search/TestQueryRescorer.java
index 2e95653..f885f56 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestQueryRescorer.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestQueryRescorer.java
@@ -20,7 +20,6 @@ package org.apache.lucene.search;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
-import java.util.Set;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
@@ -423,10 +422,6 @@ public class TestQueryRescorer extends LuceneTestCase {
return new Weight(FixedScoreQuery.this) {
@Override
- public void extractTerms(Set<Term> terms) {
- }
-
- @Override
public Scorer scorer(final LeafReaderContext context) throws IOException {
return new Scorer(this) {
@@ -500,6 +495,11 @@ public class TestQueryRescorer extends LuceneTestCase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
+ @Override
public String toString(String field) {
return "FixedScoreQuery " + idToNum.length + " ids; reverse=" + reverse;
}
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestQueryVisitor.java b/lucene/core/src/test/org/apache/lucene/search/TestQueryVisitor.java
new file mode 100644
index 0000000..f1a4310
--- /dev/null
+++ b/lucene/core/src/test/org/apache/lucene/search/TestQueryVisitor.java
@@ -0,0 +1,333 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.search;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.spans.SpanNearQuery;
+import org.apache.lucene.search.spans.SpanQuery;
+import org.apache.lucene.search.spans.SpanTermQuery;
+import org.apache.lucene.util.LuceneTestCase;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+
+public class TestQueryVisitor extends LuceneTestCase {
+
+ private static final Query query = new BooleanQuery.Builder()
+ .add(new TermQuery(new Term("field1", "t1")), BooleanClause.Occur.MUST)
+ .add(new BooleanQuery.Builder()
+ .add(new TermQuery(new Term("field1", "tm2")), BooleanClause.Occur.SHOULD)
+ .add(new BoostQuery(new TermQuery(new Term("field1", "tm3")), 2), BooleanClause.Occur.SHOULD)
+ .build(), BooleanClause.Occur.MUST)
+ .add(new BoostQuery(new PhraseQuery.Builder()
+ .add(new Term("field1", "term4"))
+ .add(new Term("field1", "term5"))
+ .build(), 3), BooleanClause.Occur.MUST)
+ .add(new SpanNearQuery(new SpanQuery[]{
+ new SpanTermQuery(new Term("field1", "term6")),
+ new SpanTermQuery(new Term("field1", "term7"))
+ }, 2, true), BooleanClause.Occur.MUST)
+ .add(new TermQuery(new Term("field1", "term8")), BooleanClause.Occur.MUST_NOT)
+ .add(new PrefixQuery(new Term("field1", "term9")), BooleanClause.Occur.SHOULD)
+ .add(new BoostQuery(new BooleanQuery.Builder()
+ .add(new BoostQuery(new TermQuery(new Term("field2", "term10")), 3), BooleanClause.Occur.MUST)
+ .build(), 2), BooleanClause.Occur.SHOULD)
+ .build();
+
+ public void testExtractTermsEquivalent() {
+ Set<Term> terms = new HashSet<>();
+ Set<Term> expected = new HashSet<>(Arrays.asList(
+ new Term("field1", "t1"), new Term("field1", "tm2"),
+ new Term("field1", "tm3"), new Term("field1", "term4"),
+ new Term("field1", "term5"), new Term("field1", "term6"),
+ new Term("field1", "term7"), new Term("field2", "term10")
+ ));
+ query.visit(QueryVisitor.termCollector(terms));
+ assertThat(terms, equalTo(expected));
+ }
+
+ public void extractAllTerms() {
+ Set<Term> terms = new HashSet<>();
+ QueryVisitor visitor = new QueryVisitor() {
+ @Override
+ public void consumeTerms(Query query, Term... ts) {
+ terms.addAll(Arrays.asList(ts));
+ }
+ @Override
+ public QueryVisitor getSubVisitor(BooleanClause.Occur occur, Query parent) {
+ return this;
+ }
+ };
+ Set<Term> expected = new HashSet<>(Arrays.asList(
+ new Term("field1", "t1"), new Term("field1", "tm2"),
+ new Term("field1", "tm3"), new Term("field1", "term4"),
+ new Term("field1", "term5"), new Term("field1", "term6"),
+ new Term("field1", "term7"), new Term("field1", "term8"),
+ new Term("field2", "term10")
+ ));
+ query.visit(visitor);
+ assertThat(terms, equalTo(expected));
+ }
+
+ public void extractTermsFromField() {
+ final Set<Term> actual = new HashSet<>();
+ Set<Term> expected = new HashSet<>(Arrays.asList(new Term("field2", "term10")));
+ query.visit(new QueryVisitor(){
+ @Override
+ public boolean acceptField(String field) {
+ return "field2".equals(field);
+ }
+ @Override
+ public void consumeTerms(Query query, Term... terms) {
+ actual.addAll(Arrays.asList(terms));
+ }
+ });
+ assertThat(actual, equalTo(expected));
+ }
+
+ static class BoostedTermExtractor extends QueryVisitor {
+
+ final float boost;
+ final Map<Term, Float> termsToBoosts;
+
+ BoostedTermExtractor(float boost, Map<Term, Float> termsToBoosts) {
+ this.boost = boost;
+ this.termsToBoosts = termsToBoosts;
+ }
+
+ @Override
+ public void consumeTerms(Query query, Term... terms) {
+ for (Term term : terms) {
+ termsToBoosts.put(term, boost);
+ }
+ }
+
+ @Override
+ public QueryVisitor getSubVisitor(BooleanClause.Occur occur, Query parent) {
+ if (parent instanceof BoostQuery) {
+ return new BoostedTermExtractor(boost * ((BoostQuery)parent).getBoost(), termsToBoosts);
+ }
+ return super.getSubVisitor(occur, parent);
+ }
+ }
+
+ public void testExtractTermsAndBoosts() {
+ Map<Term, Float> termsToBoosts = new HashMap<>();
+ query.visit(new BoostedTermExtractor(1, termsToBoosts));
+ Map<Term, Float> expected = new HashMap<>();
+ expected.put(new Term("field1", "t1"), 1f);
+ expected.put(new Term("field1", "tm2"), 1f);
+ expected.put(new Term("field1", "tm3"), 2f);
+ expected.put(new Term("field1", "term4"), 3f);
+ expected.put(new Term("field1", "term5"), 3f);
+ expected.put(new Term("field1", "term6"), 1f);
+ expected.put(new Term("field1", "term7"), 1f);
+ expected.put(new Term("field2", "term10"), 6f);
+ assertThat(termsToBoosts, equalTo(expected));
+ }
+
+ public void testLeafQueryTypeCounts() {
+ Map<Class<? extends Query>, Integer> queryCounts = new HashMap<>();
+ query.visit(new QueryVisitor() {
+
+ private void countQuery(Query q) {
+ queryCounts.compute(q.getClass(), (query, i) -> {
+ if (i == null) {
+ return 1;
+ }
+ return i + 1;
+ });
+ }
+
+ @Override
+ public void consumeTerms(Query query, Term... terms) {
+ countQuery(query);
+ }
+
+ @Override
+ public void visitLeaf(Query query) {
+ countQuery(query);
+ }
+
+ });
+ assertEquals(4, queryCounts.get(TermQuery.class).intValue());
+ assertEquals(1, queryCounts.get(PhraseQuery.class).intValue());
+ }
+
+ static abstract class QueryNode extends QueryVisitor {
+
+ final List<QueryNode> children = new ArrayList<>();
+
+ abstract int getWeight();
+ abstract void collectTerms(Set<Term> terms);
+ abstract boolean nextTermSet();
+
+ @Override
+ public QueryVisitor getSubVisitor(BooleanClause.Occur occur, Query parent) {
+ if (occur == BooleanClause.Occur.MUST || occur == BooleanClause.Occur.FILTER) {
+ QueryNode n = new ConjunctionNode();
+ children.add(n);
+ return n;
+ }
+ if (occur == BooleanClause.Occur.MUST_NOT) {
+ return QueryVisitor.EMPTY_VISITOR;
+ }
+ if (parent instanceof BooleanQuery) {
+ BooleanQuery bq = (BooleanQuery) parent;
+ if (bq.getClauses(BooleanClause.Occur.MUST).size() > 0 || bq.getClauses(BooleanClause.Occur.FILTER).size() > 0) {
+ return QueryVisitor.EMPTY_VISITOR;
+ }
+ }
+ DisjunctionNode n = new DisjunctionNode();
+ children.add(n);
+ return n;
+ }
+ }
+
+ static class TermNode extends QueryNode {
+
+ final Term term;
+
+ TermNode(Term term) {
+ this.term = term;
+ }
+
+ @Override
+ int getWeight() {
+ return term.text().length();
+ }
+
+ @Override
+ void collectTerms(Set<Term> terms) {
+ terms.add(term);
+ }
+
+ @Override
+ boolean nextTermSet() {
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "TERM(" + term.toString() + ")";
+ }
+ }
+
+ static class ConjunctionNode extends QueryNode {
+
+ @Override
+ int getWeight() {
+ children.sort(Comparator.comparingInt(QueryNode::getWeight));
+ return children.get(0).getWeight();
+ }
+
+ @Override
+ void collectTerms(Set<Term> terms) {
+ children.sort(Comparator.comparingInt(QueryNode::getWeight));
+ children.get(0).collectTerms(terms);
+ }
+
+ @Override
+ boolean nextTermSet() {
+ children.sort(Comparator.comparingInt(QueryNode::getWeight));
+ if (children.get(0).nextTermSet()) {
+ return true;
+ }
+ if (children.size() == 1) {
+ return false;
+ }
+ children.remove(0);
+ return true;
+ }
+
+ @Override
+ public void consumeTerms(Query query, Term... terms) {
+ for (Term term : terms) {
+ children.add(new TermNode(term));
+ }
+ }
+
+ @Override
+ public String toString() {
+ return children.stream().map(QueryNode::toString).collect(Collectors.joining(",", "AND(", ")"));
+ }
+ }
+
+ static class DisjunctionNode extends QueryNode {
+
+ @Override
+ int getWeight() {
+ children.sort(Comparator.comparingInt(QueryNode::getWeight).reversed());
+ return children.get(0).getWeight();
+ }
+
+ @Override
+ void collectTerms(Set<Term> terms) {
+ for (QueryNode child : children) {
+ child.collectTerms(terms);
+ }
+ }
+
+ @Override
+ boolean nextTermSet() {
+ boolean next = false;
+ for (QueryNode child : children) {
+ next |= child.nextTermSet();
+ }
+ return next;
+ }
+
+ @Override
+ public void consumeTerms(Query query, Term... terms) {
+ for (Term term : terms) {
+ children.add(new TermNode(term));
+ }
+ }
+
+ @Override
+ public String toString() {
+ return children.stream().map(QueryNode::toString).collect(Collectors.joining(",", "OR(", ")"));
+ }
+ }
+
+ public void testExtractMatchingTermSet() {
+ QueryNode extractor = new ConjunctionNode();
+ query.visit(extractor);
+ Set<Term> minimumTermSet = new HashSet<>();
+ extractor.collectTerms(minimumTermSet);
+
+ Set<Term> expected1 = new HashSet<>(Collections.singletonList(new Term("field1", "t1")));
+ assertThat(minimumTermSet, equalTo(expected1));
+ assertTrue(extractor.nextTermSet());
+ Set<Term> expected2 = new HashSet<>(Arrays.asList(new Term("field1", "tm2"), new Term("field1", "tm3")));
+ minimumTermSet.clear();
+ extractor.collectTerms(minimumTermSet);
+ assertThat(minimumTermSet, equalTo(expected2));
+ }
+
+}
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestRegexpRandom2.java b/lucene/core/src/test/org/apache/lucene/search/TestRegexpRandom2.java
index 78a4352..9c2810c 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestRegexpRandom2.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestRegexpRandom2.java
@@ -40,9 +40,9 @@ import org.apache.lucene.util.CharsRefBuilder;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.TestUtil;
import org.apache.lucene.util.UnicodeUtil;
+import org.apache.lucene.util.automaton.Automaton;
import org.apache.lucene.util.automaton.AutomatonTestUtil;
import org.apache.lucene.util.automaton.CharacterRunAutomaton;
-import org.apache.lucene.util.automaton.Automaton;
import org.apache.lucene.util.automaton.RegExp;
/**
@@ -139,6 +139,11 @@ public class TestRegexpRandom2 extends LuceneTestCase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
+ @Override
public boolean equals(Object obj) {
if (super.equals(obj) == false) {
return false;
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestScorerPerf.java b/lucene/core/src/test/org/apache/lucene/search/TestScorerPerf.java
index be3f969..20e7857 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestScorerPerf.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestScorerPerf.java
@@ -142,7 +142,12 @@ public class TestScorerPerf extends LuceneTestCase {
}
};
}
-
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
@Override
public String toString(String field) {
return "randomBitSetFilter";
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestSortRandom.java b/lucene/core/src/test/org/apache/lucene/search/TestSortRandom.java
index 136026e..9de3370 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestSortRandom.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestSortRandom.java
@@ -258,6 +258,11 @@ public class TestSortRandom extends LuceneTestCase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
+ @Override
public String toString(String field) {
return "RandomFilter(density=" + density + ")";
}
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestUsageTrackingFilterCachingPolicy.java b/lucene/core/src/test/org/apache/lucene/search/TestUsageTrackingFilterCachingPolicy.java
index c817623..74112e8 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestUsageTrackingFilterCachingPolicy.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestUsageTrackingFilterCachingPolicy.java
@@ -132,6 +132,11 @@ public class TestUsageTrackingFilterCachingPolicy extends LuceneTestCase {
};
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
}
}
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestWANDScorer.java b/lucene/core/src/test/org/apache/lucene/search/TestWANDScorer.java
index 7d1b2cb..2a48cb3 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestWANDScorer.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestWANDScorer.java
@@ -355,6 +355,11 @@ public class TestWANDScorer extends LuceneTestCase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
return new FilterWeight(query.createWeight(searcher, scoreMode, boost)) {
@Override
diff --git a/lucene/core/src/test/org/apache/lucene/search/spans/JustCompileSearchSpans.java b/lucene/core/src/test/org/apache/lucene/search/spans/JustCompileSearchSpans.java
index 3244c1d..42e4c3c 100644
--- a/lucene/core/src/test/org/apache/lucene/search/spans/JustCompileSearchSpans.java
+++ b/lucene/core/src/test/org/apache/lucene/search/spans/JustCompileSearchSpans.java
@@ -20,6 +20,7 @@ package org.apache.lucene.search.spans;
import java.io.IOException;
import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
/**
@@ -99,6 +100,11 @@ final class JustCompileSearchSpans {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ throw new UnsupportedOperationException(UNSUPPORTED_MSG);
+ }
+
+ @Override
public String toString(String field) {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
}
diff --git a/lucene/core/src/test/org/apache/lucene/search/spans/TestFieldMaskingSpanQuery.java b/lucene/core/src/test/org/apache/lucene/search/spans/TestFieldMaskingSpanQuery.java
index f72ea66..4005ae5 100644
--- a/lucene/core/src/test/org/apache/lucene/search/spans/TestFieldMaskingSpanQuery.java
+++ b/lucene/core/src/test/org/apache/lucene/search/spans/TestFieldMaskingSpanQuery.java
@@ -17,6 +17,9 @@
package org.apache.lucene.search.spans;
+import java.util.HashSet;
+import java.util.Set;
+
import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
@@ -27,6 +30,7 @@ import org.apache.lucene.search.CheckHits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.QueryUtils;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.similarities.TFIDFSimilarity;
import org.apache.lucene.store.Directory;
@@ -34,9 +38,6 @@ import org.apache.lucene.util.LuceneTestCase;
import org.junit.AfterClass;
import org.junit.BeforeClass;
-import java.util.HashSet;
-import java.util.Set;
-
import static org.apache.lucene.search.spans.SpanTestUtil.assertFinished;
import static org.apache.lucene.search.spans.SpanTestUtil.assertNext;
@@ -143,7 +144,7 @@ public class TestFieldMaskingSpanQuery extends LuceneTestCase {
QueryUtils.checkEqual(q, qr);
Set<Term> terms = new HashSet<>();
- qr.createWeight(searcher, ScoreMode.COMPLETE_NO_SCORES, 1f).extractTerms(terms);
+ qr.visit(QueryVisitor.termCollector(terms));
assertEquals(1, terms.size());
}
@@ -163,7 +164,7 @@ public class TestFieldMaskingSpanQuery extends LuceneTestCase {
QueryUtils.checkUnequal(q, qr);
Set<Term> terms = new HashSet<>();
- qr.createWeight(searcher, ScoreMode.COMPLETE_NO_SCORES, 1f).extractTerms(terms);
+ qr.visit(QueryVisitor.termCollector(terms));
assertEquals(2, terms.size());
}
@@ -177,7 +178,7 @@ public class TestFieldMaskingSpanQuery extends LuceneTestCase {
QueryUtils.checkEqual(q, qr);
HashSet<Term> set = new HashSet<>();
- qr.createWeight(searcher, ScoreMode.COMPLETE, 1f).extractTerms(set);
+ qr.visit(QueryVisitor.termCollector(set));
assertEquals(2, set.size());
}
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/DrillDownQuery.java b/lucene/facet/src/java/org/apache/lucene/facet/DrillDownQuery.java
index 1ea2613..badfe81 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/DrillDownQuery.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/DrillDownQuery.java
@@ -30,6 +30,7 @@ import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.TermQuery;
/**
@@ -149,6 +150,11 @@ public final class DrillDownQuery extends Query {
return getBooleanQuery().toString(field);
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
private BooleanQuery getBooleanQuery() {
BooleanQuery.Builder bq = new BooleanQuery.Builder();
if (baseQuery != null) {
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/DrillSidewaysQuery.java b/lucene/facet/src/java/org/apache/lucene/facet/DrillSidewaysQuery.java
index 82c642a..748ed82 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/DrillSidewaysQuery.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/DrillSidewaysQuery.java
@@ -20,12 +20,10 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.facet.DrillSidewaysScorer.DocsAndCost;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.BulkScorer;
import org.apache.lucene.search.Collector;
import org.apache.lucene.search.ConstantScoreScorer;
@@ -33,6 +31,7 @@ import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
@@ -78,6 +77,11 @@ class DrillSidewaysQuery extends Query {
return new DrillSidewaysQuery(newQuery, drillDownCollector, drillSidewaysCollectors, drillDownQueries, scoreSubDocsAtOnce);
}
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
@Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
@@ -89,9 +93,6 @@ class DrillSidewaysQuery extends Query {
return new Weight(DrillSidewaysQuery.this) {
@Override
- public void extractTerms(Set<Term> terms) {}
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
return baseWeight.explain(context, doc);
}
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRange.java b/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRange.java
index afc4c4f..ad0ba67 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRange.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/range/DoubleRange.java
@@ -28,6 +28,7 @@ import org.apache.lucene.search.DoubleValues;
import org.apache.lucene.search.DoubleValuesSource;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TwoPhaseIterator;
@@ -142,6 +143,11 @@ public final class DoubleRange extends Range {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
+ @Override
public Query rewrite(IndexReader reader) throws IOException {
if (fastMatchQuery != null) {
final Query fastMatchRewritten = fastMatchQuery.rewrite(reader);
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/range/LongRange.java b/lucene/facet/src/java/org/apache/lucene/facet/range/LongRange.java
index eed293f..f69ba76 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/range/LongRange.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/range/LongRange.java
@@ -28,6 +28,7 @@ import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.LongValues;
import org.apache.lucene.search.LongValuesSource;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TwoPhaseIterator;
@@ -134,6 +135,11 @@ public final class LongRange extends Range {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
+ @Override
public Query rewrite(IndexReader reader) throws IOException {
if (fastMatchQuery != null) {
final Query fastMatchRewritten = fastMatchQuery.rewrite(reader);
diff --git a/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java b/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java
index 288f6cc..6dc790d 100644
--- a/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java
+++ b/lucene/facet/src/test/org/apache/lucene/facet/TestDrillSideways.java
@@ -52,6 +52,7 @@ import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
@@ -750,6 +751,11 @@ public class TestDrillSideways extends FacetTestCase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
+ @Override
public String toString(String field) {
return "drillSidewaysTestFilter";
}
diff --git a/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java b/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java
index 2408286..441675c 100644
--- a/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java
+++ b/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java
@@ -53,6 +53,7 @@ import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.LongValuesSource;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
@@ -715,6 +716,11 @@ public class TestRangeFacetCounts extends FacetTestCase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ in.visit(visitor);
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
final Weight in = this.in.createWeight(searcher, scoreMode, boost);
return new FilterWeight(in) {
diff --git a/lucene/highlighter/src/java/org/apache/lucene/search/highlight/QueryTermExtractor.java b/lucene/highlighter/src/java/org/apache/lucene/search/highlight/QueryTermExtractor.java
index 9d3784a..0b5738f 100644
--- a/lucene/highlighter/src/java/org/apache/lucene/search/highlight/QueryTermExtractor.java
+++ b/lucene/highlighter/src/java/org/apache/lucene/search/highlight/QueryTermExtractor.java
@@ -15,19 +15,20 @@
* limitations under the License.
*/
package org.apache.lucene.search.highlight;
+
import java.io.IOException;
import java.util.HashSet;
-import java.util.Iterator;
+import java.util.Set;
+import java.util.function.Predicate;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
-import org.apache.lucene.search.ScoreMode;
+import org.apache.lucene.search.QueryVisitor;
/**
* Utility class used to extract the terms used in a query, plus any weights.
@@ -100,10 +101,10 @@ public final class QueryTermExtractor
* @param fieldName The fieldName used to filter query terms
* @return an array of the terms used in a query, plus their weights.
*/
- public static final WeightedTerm[] getTerms(Query query, boolean prohibited, String fieldName)
- {
- HashSet<WeightedTerm> terms=new HashSet<>();
- getTerms(query, 1f, terms,prohibited,fieldName);
+ public static WeightedTerm[] getTerms(Query query, boolean prohibited, String fieldName) {
+ HashSet<WeightedTerm> terms = new HashSet<>();
+ Predicate<String> fieldSelector = fieldName == null ? f -> true : fieldName::equals;
+ query.visit(new BoostedTermExtractor(1, terms, prohibited, fieldSelector));
return terms.toArray(new WeightedTerm[0]);
}
@@ -119,50 +120,45 @@ public final class QueryTermExtractor
return getTerms(query,prohibited,null);
}
- private static final void getTerms(Query query, float boost, HashSet<WeightedTerm> terms, boolean prohibited, String fieldName) {
- try {
- if (query instanceof BoostQuery) {
- BoostQuery boostQuery = (BoostQuery) query;
- getTerms(boostQuery.getQuery(), boost * boostQuery.getBoost(), terms, prohibited, fieldName);
- } else if (query instanceof BooleanQuery)
- getTermsFromBooleanQuery((BooleanQuery) query, boost, terms, prohibited, fieldName);
- else {
- HashSet<Term> nonWeightedTerms = new HashSet<>();
- try {
- EMPTY_INDEXSEARCHER.createWeight(EMPTY_INDEXSEARCHER.rewrite(query), ScoreMode.COMPLETE_NO_SCORES, 1).extractTerms(nonWeightedTerms);
- } catch (IOException bogus) {
- throw new RuntimeException("Should not happen on an empty index", bogus);
- }
- for (Iterator<Term> iter = nonWeightedTerms.iterator(); iter.hasNext(); ) {
- Term term = iter.next();
- if ((fieldName == null) || (term.field().equals(fieldName))) {
- terms.add(new WeightedTerm(boost, term.text()));
- }
- }
+ private static class BoostedTermExtractor extends QueryVisitor {
+
+ final float boost;
+ final Set<WeightedTerm> terms;
+ final boolean includeProhibited;
+ final Predicate<String> fieldSelector;
+
+ private BoostedTermExtractor(float boost, Set<WeightedTerm> terms, boolean includeProhibited,
+ Predicate<String> fieldSelector) {
+ this.boost = boost;
+ this.terms = terms;
+ this.includeProhibited = includeProhibited;
+ this.fieldSelector = fieldSelector;
+ }
+
+ @Override
+ public boolean acceptField(String field) {
+ return fieldSelector.test(field);
+ }
+
+ @Override
+ public void consumeTerms(Query query, Term... terms) {
+ for (Term term : terms) {
+ this.terms.add(new WeightedTerm(boost, term.text()));
}
- } catch (UnsupportedOperationException ignore) {
- //this is non-fatal for our purposes
}
- }
- /**
- * extractTerms is currently the only query-independent means of introspecting queries but it only reveals
- * a list of terms for that query - not the boosts each individual term in that query may or may not have.
- * "Container" queries such as BooleanQuery should be unwrapped to get at the boost info held
- * in each child element.
- * Some discussion around this topic here:
- * http://www.gossamer-threads.com/lists/lucene/java-dev/34208?search_string=introspection;#34208
- * Unfortunately there seemed to be limited interest in requiring all Query objects to implement
- * something common which would allow access to child queries so what follows here are query-specific
- * implementations for accessing embedded query elements.
- */
- private static final void getTermsFromBooleanQuery(BooleanQuery query, float boost, HashSet<WeightedTerm> terms, boolean prohibited, String fieldName)
- {
- for (BooleanClause clause : query)
- {
- if (prohibited || clause.getOccur()!=BooleanClause.Occur.MUST_NOT)
- getTerms(clause.getQuery(), boost, terms, prohibited, fieldName);
+ @Override
+ public QueryVisitor getSubVisitor(BooleanClause.Occur occur, Query parent) {
+ if (parent instanceof BoostQuery) {
+ float newboost = boost * ((BoostQuery)parent).getBoost();
+ return new BoostedTermExtractor(newboost, terms, includeProhibited, fieldSelector);
+ }
+ if (occur == BooleanClause.Occur.MUST_NOT && includeProhibited == false) {
+ return QueryVisitor.EMPTY_VISITOR;
+ }
+ return this;
}
+
}
}
diff --git a/lucene/highlighter/src/java/org/apache/lucene/search/highlight/WeightedSpanTermExtractor.java b/lucene/highlighter/src/java/org/apache/lucene/search/highlight/WeightedSpanTermExtractor.java
index bc02621..ee0a187 100644
--- a/lucene/highlighter/src/java/org/apache/lucene/search/highlight/WeightedSpanTermExtractor.java
+++ b/lucene/highlighter/src/java/org/apache/lucene/search/highlight/WeightedSpanTermExtractor.java
@@ -51,6 +51,7 @@ import org.apache.lucene.search.MultiPhraseQuery;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.SynonymQuery;
import org.apache.lucene.search.TermQuery;
@@ -308,10 +309,10 @@ public class WeightedSpanTermExtractor {
for (final String field : fieldNames) {
final SpanQuery rewrittenQuery = (SpanQuery) spanQuery.rewrite(getLeafContext().reader());
queries.put(field, rewrittenQuery);
- rewrittenQuery.createWeight(searcher, ScoreMode.COMPLETE_NO_SCORES, boost).extractTerms(nonWeightedTerms);
+ rewrittenQuery.visit(QueryVisitor.termCollector(nonWeightedTerms));
}
} else {
- spanQuery.createWeight(searcher, ScoreMode.COMPLETE_NO_SCORES, boost).extractTerms(nonWeightedTerms);
+ spanQuery.visit(QueryVisitor.termCollector(nonWeightedTerms));
}
List<PositionSpan> spanPositions = new ArrayList<>();
@@ -378,7 +379,7 @@ public class WeightedSpanTermExtractor {
protected void extractWeightedTerms(Map<String,WeightedSpanTerm> terms, Query query, float boost) throws IOException {
Set<Term> nonWeightedTerms = new HashSet<>();
final IndexSearcher searcher = new IndexSearcher(getLeafContext());
- searcher.createWeight(searcher.rewrite(query), ScoreMode.COMPLETE_NO_SCORES, 1).extractTerms(nonWeightedTerms);
+ searcher.rewrite(query).visit(QueryVisitor.termCollector(nonWeightedTerms));
for (final Term queryTerm : nonWeightedTerms) {
diff --git a/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/MemoryIndexOffsetStrategy.java b/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/MemoryIndexOffsetStrategy.java
index 30dbdd4..1f4455f 100644
--- a/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/MemoryIndexOffsetStrategy.java
+++ b/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/MemoryIndexOffsetStrategy.java
@@ -19,10 +19,8 @@ package org.apache.lucene.search.uhighlight;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.List;
-import java.util.function.Function;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.FilteringTokenFilter;
@@ -30,7 +28,6 @@ import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.memory.MemoryIndex;
-import org.apache.lucene.search.Query;
import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.util.automaton.Automata;
import org.apache.lucene.util.automaton.CharacterRunAutomaton;
@@ -47,21 +44,19 @@ public class MemoryIndexOffsetStrategy extends AnalysisOffsetStrategy {
private final LeafReader memIndexLeafReader;
private final CharacterRunAutomaton preMemIndexFilterAutomaton;
- public MemoryIndexOffsetStrategy(UHComponents components, Analyzer analyzer,
- Function<Query, Collection<Query>> multiTermQueryRewrite) {
+ public MemoryIndexOffsetStrategy(UHComponents components, Analyzer analyzer) {
super(components, analyzer);
boolean storePayloads = components.getPhraseHelper().hasPositionSensitivity(); // might be needed
memoryIndex = new MemoryIndex(true, storePayloads);//true==store offsets
memIndexLeafReader = (LeafReader) memoryIndex.createSearcher().getIndexReader(); // appears to be re-usable
// preFilter for MemoryIndex
- preMemIndexFilterAutomaton = buildCombinedAutomaton(components, multiTermQueryRewrite);
+ preMemIndexFilterAutomaton = buildCombinedAutomaton(components);
}
/**
* Build one {@link CharacterRunAutomaton} matching any term the query might match.
*/
- private static CharacterRunAutomaton buildCombinedAutomaton(UHComponents components,
- Function<Query, Collection<Query>> multiTermQueryRewrite) {
+ private static CharacterRunAutomaton buildCombinedAutomaton(UHComponents components) {
List<CharacterRunAutomaton> allAutomata = new ArrayList<>();
if (components.getTerms().length > 0) {
allAutomata.add(new CharacterRunAutomaton(Automata.makeStringUnion(Arrays.asList(components.getTerms()))));
@@ -69,7 +64,7 @@ public class MemoryIndexOffsetStrategy extends AnalysisOffsetStrategy {
Collections.addAll(allAutomata, components.getAutomata());
for (SpanQuery spanQuery : components.getPhraseHelper().getSpanQueries()) {
Collections.addAll(allAutomata,
- MultiTermHighlighting.extractAutomata(spanQuery, components.getFieldMatcher(), true, multiTermQueryRewrite));//true==lookInSpan
+ MultiTermHighlighting.extractAutomata(spanQuery, components.getFieldMatcher(), true));//true==lookInSpan
}
if (allAutomata.size() == 1) {
diff --git a/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/MultiTermHighlighting.java b/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/MultiTermHighlighting.java
index 57d5afa..d079599 100644
--- a/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/MultiTermHighlighting.java
+++ b/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/MultiTermHighlighting.java
@@ -17,33 +17,20 @@
package org.apache.lucene.search.uhighlight;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
import java.util.List;
-import java.util.function.Function;
import java.util.function.Predicate;
-import org.apache.lucene.queries.function.FunctionScoreQuery;
import org.apache.lucene.search.AutomatonQuery;
import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.BoostQuery;
-import org.apache.lucene.search.ConstantScoreQuery;
-import org.apache.lucene.search.DisjunctionMaxQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.Query;
-import org.apache.lucene.search.spans.SpanBoostQuery;
-import org.apache.lucene.search.spans.SpanMultiTermQueryWrapper;
-import org.apache.lucene.search.spans.SpanNearQuery;
-import org.apache.lucene.search.spans.SpanNotQuery;
-import org.apache.lucene.search.spans.SpanOrQuery;
-import org.apache.lucene.search.spans.SpanPositionCheckQuery;
+import org.apache.lucene.search.QueryVisitor;
+import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.util.UnicodeUtil;
import org.apache.lucene.util.automaton.Automata;
import org.apache.lucene.util.automaton.Automaton;
import org.apache.lucene.util.automaton.ByteRunAutomaton;
import org.apache.lucene.util.automaton.CharacterRunAutomaton;
-import org.apache.lucene.util.automaton.LevenshteinAutomata;
import org.apache.lucene.util.automaton.Operations;
/**
@@ -51,7 +38,7 @@ import org.apache.lucene.util.automaton.Operations;
*
* @lucene.internal
*/
-class MultiTermHighlighting {
+final class MultiTermHighlighting {
private MultiTermHighlighting() {
}
@@ -59,138 +46,117 @@ class MultiTermHighlighting {
* Extracts MultiTermQueries that match the provided field predicate.
* Returns equivalent automata that will match terms.
*/
- public static CharacterRunAutomaton[] extractAutomata(Query query,
- Predicate<String> fieldMatcher,
- boolean lookInSpan,
- Function<Query, Collection<Query>> preRewriteFunc) {
- // TODO Lucene needs a Query visitor API! LUCENE-3041
-
- List<CharacterRunAutomaton> list = new ArrayList<>();
- Collection<Query> customSubQueries = preRewriteFunc.apply(query);
- if (customSubQueries != null) {
- for (Query sub : customSubQueries) {
- list.addAll(Arrays.asList(extractAutomata(sub, fieldMatcher, lookInSpan, preRewriteFunc)));
- }
- } else if (query instanceof BooleanQuery) {
- for (BooleanClause clause : (BooleanQuery) query) {
- if (!clause.isProhibited()) {
- list.addAll(Arrays.asList(extractAutomata(clause.getQuery(), fieldMatcher, lookInSpan, preRewriteFunc)));
- }
- }
- } else if (query instanceof ConstantScoreQuery) {
- list.addAll(Arrays.asList(extractAutomata(((ConstantScoreQuery) query).getQuery(), fieldMatcher, lookInSpan,
- preRewriteFunc)));
- } else if (query instanceof BoostQuery) {
- list.addAll(Arrays.asList(extractAutomata(((BoostQuery) query).getQuery(), fieldMatcher, lookInSpan,
- preRewriteFunc)));
- } else if (query instanceof FunctionScoreQuery) {
- list.addAll(Arrays.asList(extractAutomata(((FunctionScoreQuery) query).getWrappedQuery(), fieldMatcher,
- lookInSpan, preRewriteFunc)));
- } else if (query instanceof DisjunctionMaxQuery) {
- for (Query sub : ((DisjunctionMaxQuery) query).getDisjuncts()) {
- list.addAll(Arrays.asList(extractAutomata(sub, fieldMatcher, lookInSpan, preRewriteFunc)));
- }
- } else if (lookInSpan && query instanceof SpanOrQuery) {
- for (Query sub : ((SpanOrQuery) query).getClauses()) {
- list.addAll(Arrays.asList(extractAutomata(sub, fieldMatcher, lookInSpan, preRewriteFunc)));
- }
- } else if (lookInSpan && query instanceof SpanNearQuery) {
- for (Query sub : ((SpanNearQuery) query).getClauses()) {
- list.addAll(Arrays.asList(extractAutomata(sub, fieldMatcher, lookInSpan, preRewriteFunc)));
- }
- } else if (lookInSpan && query instanceof SpanNotQuery) {
- list.addAll(Arrays.asList(extractAutomata(((SpanNotQuery) query).getInclude(), fieldMatcher, lookInSpan,
- preRewriteFunc)));
- } else if (lookInSpan && query instanceof SpanPositionCheckQuery) {
- list.addAll(Arrays.asList(extractAutomata(((SpanPositionCheckQuery) query).getMatch(), fieldMatcher, lookInSpan,
- preRewriteFunc)));
- } else if (lookInSpan && query instanceof SpanBoostQuery) {
- list.addAll(Arrays.asList(extractAutomata(((SpanBoostQuery) query).getQuery(), fieldMatcher, lookInSpan,
- preRewriteFunc)));
- } else if (lookInSpan && query instanceof SpanMultiTermQueryWrapper) {
- list.addAll(Arrays.asList(extractAutomata(((SpanMultiTermQueryWrapper<?>) query).getWrappedQuery(),
- fieldMatcher, lookInSpan, preRewriteFunc)));
- } else if (query instanceof FuzzyQuery) {
- final FuzzyQuery fq = (FuzzyQuery) query;
- if (fieldMatcher.test(fq.getField())) {
- String utf16 = fq.getTerm().text();
- int termText[] = new int[utf16.codePointCount(0, utf16.length())];
- for (int cp, i = 0, j = 0; i < utf16.length(); i += Character.charCount(cp)) {
- termText[j++] = cp = utf16.codePointAt(i);
- }
- int termLength = termText.length;
- int prefixLength = Math.min(fq.getPrefixLength(), termLength);
- String suffix = UnicodeUtil.newString(termText, prefixLength, termText.length - prefixLength);
- LevenshteinAutomata builder = new LevenshteinAutomata(suffix, fq.getTranspositions());
- String prefix = UnicodeUtil.newString(termText, 0, prefixLength);
- Automaton automaton = builder.toAutomaton(fq.getMaxEdits(), prefix);
- list.add(new CharacterRunAutomaton(automaton) {
- @Override
- public String toString() {
- return fq.toString();
- }
- });
+ static CharacterRunAutomaton[] extractAutomata(Query query, Predicate<String> fieldMatcher, boolean lookInSpan) {
+
+ AutomataCollector collector = new AutomataCollector(lookInSpan, fieldMatcher);
+ query.visit(collector);
+ return collector.runAutomata.toArray(new CharacterRunAutomaton[0]);
+ }
+
+ private static class AutomataCollector extends QueryVisitor {
+
+ List<CharacterRunAutomaton> runAutomata = new ArrayList<>();
+ final boolean lookInSpan;
+ final Predicate<String> fieldMatcher;
+
+ private AutomataCollector(boolean lookInSpan, Predicate<String> fieldMatcher) {
+ this.lookInSpan = lookInSpan;
+ this.fieldMatcher = fieldMatcher;
+ }
+
+ @Override
+ public boolean acceptField(String field) {
+ return fieldMatcher.test(field);
+ }
+
+ @Override
+ public QueryVisitor getSubVisitor(BooleanClause.Occur occur, Query parent) {
+ if (lookInSpan == false && parent instanceof SpanQuery) {
+ return QueryVisitor.EMPTY_VISITOR;
}
- } else if (query instanceof AutomatonQuery) {
- final AutomatonQuery aq = (AutomatonQuery) query;
- if (fieldMatcher.test(aq.getField())) {
+ return super.getSubVisitor(occur, parent);
+ }
- if (aq.isAutomatonBinary() == false) { // note: is the case for WildcardQuery, RegexpQuery
- list.add(new CharacterRunAutomaton(aq.getAutomaton()) {
+ @Override
+ public void visitLeaf(Query query) {
+ if (query instanceof AutomatonQuery) {
+ AutomatonQuery aq = (AutomatonQuery) query;
+ if (aq.isAutomatonBinary() == false) {
+ // WildcardQuery, RegexpQuery
+ runAutomata.add(new CharacterRunAutomaton(aq.getAutomaton()) {
@Override
public String toString() {
- return aq.toString();
+ return query.toString();
}
});
- } else { // note: is the case for PrefixQuery, TermRangeQuery
- // byte oriented automaton:
- list.add(new CharacterRunAutomaton(Automata.makeEmpty()) { // empty here is bogus just to satisfy API
- // TODO can we get access to the aq.compiledAutomaton.runAutomaton ?
- ByteRunAutomaton byteRunAutomaton =
- new ByteRunAutomaton(aq.getAutomaton(), true, Operations.DEFAULT_MAX_DETERMINIZED_STATES);
-
- @Override
- public boolean run(char[] chars, int offset, int length) {
- int state = 0;
- final int maxIdx = offset + length;
- for (int i = offset; i < maxIdx; i++) {
- final int code = chars[i];
- int b;
- // UTF16 to UTF8 (inlined logic from UnicodeUtil.UTF16toUTF8 )
- if (code < 0x80) {
- state = byteRunAutomaton.step(state, code);
- if (state == -1) return false;
- } else if (code < 0x800) {
- b = (0xC0 | (code >> 6));
- state = byteRunAutomaton.step(state, b);
- if (state == -1) return false;
- b = (0x80 | (code & 0x3F));
- state = byteRunAutomaton.step(state, b);
- if (state == -1) return false;
- } else {
- // more complex
- byte[] utf8Bytes = new byte[4 * (maxIdx - i)];
- int utf8Len = UnicodeUtil.UTF16toUTF8(chars, i, maxIdx - i, utf8Bytes);
- for (int utfIdx = 0; utfIdx < utf8Len; utfIdx++) {
- state = byteRunAutomaton.step(state, utf8Bytes[utfIdx] & 0xFF);
- if (state == -1) return false;
- }
- break;
- }
- }
- return byteRunAutomaton.isAccept(state);
- }
-
+ }
+ else {
+ runAutomata.add(binaryToCharRunAutomaton(aq.getAutomaton(), query.toString()));
+ }
+ }
+ else if (query instanceof FuzzyQuery) {
+ FuzzyQuery fq = (FuzzyQuery) query;
+ if (fq.getMaxEdits() == 0 || fq.getPrefixLength() >= fq.getTerm().text().length()) {
+ consumeTerms(query, fq.getTerm());
+ }
+ else {
+ runAutomata.add(new CharacterRunAutomaton(fq.toAutomaton()){
@Override
public String toString() {
- return aq.toString();
+ return query.toString();
}
});
}
-
}
}
- return list.toArray(new CharacterRunAutomaton[list.size()]);
+
}
+ private static CharacterRunAutomaton binaryToCharRunAutomaton(Automaton binaryAutomaton, String description) {
+ return new CharacterRunAutomaton(Automata.makeEmpty()) { // empty here is bogus just to satisfy API
+ // TODO can we get access to the aq.compiledAutomaton.runAutomaton ?
+ ByteRunAutomaton byteRunAutomaton =
+ new ByteRunAutomaton(binaryAutomaton, true, Operations.DEFAULT_MAX_DETERMINIZED_STATES);
+
+ @Override
+ public String toString() {
+ return description;
+ }
+
+ @Override
+ public boolean run(char[] chars, int offset, int length) {
+ int state = 0;
+ final int maxIdx = offset + length;
+ for (int i = offset; i < maxIdx; i++) {
+ final int code = chars[i];
+ int b;
+ // UTF16 to UTF8 (inlined logic from UnicodeUtil.UTF16toUTF8 )
+ if (code < 0x80) {
+ state = byteRunAutomaton.step(state, code);
+ if (state == -1) return false;
+ } else if (code < 0x800) {
+ b = (0xC0 | (code >> 6));
+ state = byteRunAutomaton.step(state, b);
+ if (state == -1) return false;
+ b = (0x80 | (code & 0x3F));
+ state = byteRunAutomaton.step(state, b);
+ if (state == -1) return false;
+ } else {
+ // more complex
+ byte[] utf8Bytes = new byte[4 * (maxIdx - i)];
+ int utf8Len = UnicodeUtil.UTF16toUTF8(chars, i, maxIdx - i, utf8Bytes);
+ for (int utfIdx = 0; utfIdx < utf8Len; utfIdx++) {
+ state = byteRunAutomaton.step(state, utf8Bytes[utfIdx] & 0xFF);
+ if (state == -1) return false;
+ }
+ break;
+ }
+ }
+ return byteRunAutomaton.isAccept(state);
+ }
+ };
+ }
+
+
+
}
diff --git a/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/OffsetsEnum.java b/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/OffsetsEnum.java
index 0e6a221..d399883 100644
--- a/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/OffsetsEnum.java
+++ b/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/OffsetsEnum.java
@@ -23,14 +23,13 @@ import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.PriorityQueue;
-import java.util.TreeSet;
import java.util.function.Supplier;
import org.apache.lucene.index.PostingsEnum;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.MatchesIterator;
import org.apache.lucene.search.Query;
-import org.apache.lucene.search.ScoreMode;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder;
import org.apache.lucene.util.IOUtils;
@@ -245,30 +244,24 @@ public abstract class OffsetsEnum implements Comparable<OffsetsEnum>, Closeable
* See {@link Passage#getMatchTerms()}. */
private BytesRef queryToTerm(Query query) {
// compute an approximate BytesRef term of a Query. We cache this since we're likely to see the same query again.
- // Our approach is to call extractTerms and visit each term in order, concatenating them with an adjoining space.
+ // Our approach is to visit each matching term in order, concatenating them with an adjoining space.
// If we don't have any (perhaps due to an MTQ like a wildcard) then we fall back on the toString() of the query.
return queryToTermMap.computeIfAbsent(query, (Query q) -> {
- try {
- BytesRefBuilder bytesRefBuilder = new BytesRefBuilder();
- UnifiedHighlighter.EMPTY_INDEXSEARCHER
- .createWeight(UnifiedHighlighter.EMPTY_INDEXSEARCHER.rewrite(q), ScoreMode.COMPLETE_NO_SCORES, 1f)
- .extractTerms(new TreeSet<Term>() {
- @Override
- public boolean add(Term term) {
+ BytesRefBuilder bytesRefBuilder = new BytesRefBuilder();
+ q.visit(new QueryVisitor() {
+ @Override
+ public void consumeTerms(Query query, Term... terms) {
+ for (Term term : terms) {
if (bytesRefBuilder.length() > 0) {
bytesRefBuilder.append((byte) ' ');
}
bytesRefBuilder.append(term.bytes());
- return true;
}
- });
- if (bytesRefBuilder.length() > 0) {
- return bytesRefBuilder.get();
}
- } catch (IOException e) {//ignore
- // go to fallback...
+ });
+ if (bytesRefBuilder.length() > 0) {
+ return bytesRefBuilder.get();
}
-
// fallback: (likely a MultiTermQuery)
return new BytesRef(q.toString());
});
diff --git a/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/PhraseHelper.java b/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/PhraseHelper.java
index ab439d0..47b770d 100644
--- a/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/PhraseHelper.java
+++ b/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/PhraseHelper.java
@@ -24,7 +24,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.TreeSet;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -40,6 +39,7 @@ import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TwoPhaseIterator;
@@ -97,20 +97,6 @@ public class PhraseHelper {
boolean[] mustRewriteHolder = {false}; // boolean wrapped in 1-ary array so it's mutable from inner class
- // When we call Weight.extractTerms, we do it on clauses that are NOT position sensitive.
- // We only want the to track a Set of bytes for the Term, not Term class with field part.
- Set<Term> extractPosInsensitiveTermsTarget = new TreeSet<Term>() {
- @Override
- public boolean add(Term term) {
- // don't call super.add; we don't actually use the superclass
- if (fieldMatcher.test(term.field())) {
- return positionInsensitiveTerms.add(term.bytes());
- } else {
- return false;
- }
- }
- };
-
// For TermQueries or other position insensitive queries, collect the Terms.
// For other Query types, WSTE will convert to an equivalent SpanQuery. NOT extracting position spans here.
new WeightedSpanTermExtractor(field) {
@@ -147,10 +133,19 @@ public class PhraseHelper {
// called on Query types that are NOT position sensitive, e.g. TermQuery
@Override
- protected void extractWeightedTerms(Map<String, WeightedSpanTerm> terms, Query query, float boost)
- throws IOException {
- query.createWeight(UnifiedHighlighter.EMPTY_INDEXSEARCHER, ScoreMode.COMPLETE_NO_SCORES, boost)
- .extractTerms(extractPosInsensitiveTermsTarget);
+ protected void extractWeightedTerms(Map<String, WeightedSpanTerm> terms, Query query, float boost) {
+ query.visit(new QueryVisitor() {
+ @Override
+ public boolean acceptField(String field) {
+ return fieldMatcher.test(field);
+ }
+ @Override
+ public void consumeTerms(Query query, Term... terms) {
+ for (Term term : terms) {
+ positionInsensitiveTerms.add(term.bytes());
+ }
+ }
+ });
}
// called on SpanQueries. Some other position-sensitive queries like PhraseQuery are converted beforehand
diff --git a/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/UnifiedHighlighter.java b/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/UnifiedHighlighter.java
index 7dcac30..f4b1ab1 100644
--- a/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/UnifiedHighlighter.java
+++ b/lucene/highlighter/src/java/org/apache/lucene/search/uhighlight/UnifiedHighlighter.java
@@ -54,8 +54,8 @@ import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreDoc;
-import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.Weight;
import org.apache.lucene.search.spans.SpanQuery;
@@ -140,11 +140,11 @@ public class UnifiedHighlighter {
private int cacheFieldValCharsThreshold = DEFAULT_CACHE_CHARS_THRESHOLD;
/**
- * Calls {@link Weight#extractTerms(Set)} on an empty index for the query.
+ * Extracts matching terms after rewriting against an empty index
*/
protected static Set<Term> extractTerms(Query query) throws IOException {
Set<Term> queryTerms = new HashSet<>();
- EMPTY_INDEXSEARCHER.createWeight(EMPTY_INDEXSEARCHER.rewrite(query), ScoreMode.COMPLETE_NO_SCORES, 1).extractTerms(queryTerms);
+ EMPTY_INDEXSEARCHER.rewrite(query).visit(QueryVisitor.termCollector(queryTerms));
return queryTerms;
}
@@ -816,7 +816,7 @@ public class UnifiedHighlighter {
|| highlightFlags.contains(HighlightFlag.WEIGHT_MATCHES); // Weight.Matches will find all
return highlightFlags.contains(HighlightFlag.MULTI_TERM_QUERY)
- ? MultiTermHighlighting.extractAutomata(query, getFieldMatcher(field), lookInSpan, this::preMultiTermQueryRewrite)
+ ? MultiTermHighlighting.extractAutomata(query, getFieldMatcher(field), lookInSpan)
: ZERO_LEN_AUTOMATA_ARRAY;
}
@@ -863,7 +863,7 @@ public class UnifiedHighlighter {
//skip using a memory index since it's pure term filtering
return new TokenStreamOffsetStrategy(components, getIndexAnalyzer());
} else {
- return new MemoryIndexOffsetStrategy(components, getIndexAnalyzer(), this::preMultiTermQueryRewrite);
+ return new MemoryIndexOffsetStrategy(components, getIndexAnalyzer());
}
case NONE_NEEDED:
return NoOpOffsetStrategy.INSTANCE;
@@ -902,19 +902,6 @@ public class UnifiedHighlighter {
return null;
}
- /**
- * When dealing with multi term queries / span queries, we may need to handle custom queries that aren't supported
- * by the default automata extraction in {@code MultiTermHighlighting}. This can be overridden to return a collection
- * of queries if appropriate, or null if nothing to do. If query is not custom, simply returning null will allow the
- * default rules to apply.
- *
- * @param query Query to be highlighted
- * @return A Collection of Query object(s) if needst o be rewritten, otherwise null.
- */
- protected Collection<Query> preMultiTermQueryRewrite(Query query) {
- return null;
- }
-
private DocIdSetIterator asDocIdSetIterator(int[] sortedDocIds) {
return new DocIdSetIterator() {
int idx = -1;
diff --git a/lucene/highlighter/src/test/org/apache/lucene/search/highlight/HighlighterTest.java b/lucene/highlighter/src/test/org/apache/lucene/search/highlight/HighlighterTest.java
index c52b8d3..c555297 100644
--- a/lucene/highlighter/src/test/org/apache/lucene/search/highlight/HighlighterTest.java
+++ b/lucene/highlighter/src/test/org/apache/lucene/search/highlight/HighlighterTest.java
@@ -72,6 +72,7 @@ import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PhraseQuery.Builder;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.RegexpQuery;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
@@ -256,6 +257,11 @@ public class HighlighterTest extends BaseTokenStreamTestCase implements Formatte
}
@Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
+ @Override
public String toString(String field) {
return null;
}
diff --git a/lucene/highlighter/src/test/org/apache/lucene/search/highlight/custom/HighlightCustomQueryTest.java b/lucene/highlighter/src/test/org/apache/lucene/search/highlight/custom/HighlightCustomQueryTest.java
index a54687d..2553a80 100644
--- a/lucene/highlighter/src/test/org/apache/lucene/search/highlight/custom/HighlightCustomQueryTest.java
+++ b/lucene/highlighter/src/test/org/apache/lucene/search/highlight/custom/HighlightCustomQueryTest.java
@@ -16,6 +16,11 @@
*/
package org.apache.lucene.search.highlight.custom;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Objects;
+
import org.apache.lucene.analysis.CannedTokenStream;
import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.analysis.MockTokenFilter;
@@ -25,6 +30,7 @@ import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
@@ -35,11 +41,6 @@ import org.apache.lucene.search.highlight.WeightedSpanTerm;
import org.apache.lucene.search.highlight.WeightedSpanTermExtractor;
import org.apache.lucene.util.LuceneTestCase;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Objects;
-
/**
* Tests the extensibility of {@link WeightedSpanTermExtractor} and
* {@link QueryScorer} in a user defined package
@@ -176,6 +177,11 @@ public class HighlightCustomQueryTest extends LuceneTestCase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.consumeTerms(this, term);
+ }
+
+ @Override
public int hashCode() {
return classHash() + Objects.hashCode(term);
}
diff --git a/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterMTQ.java b/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterMTQ.java
index 44d6f7b..34fd46f 100644
--- a/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterMTQ.java
+++ b/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterMTQ.java
@@ -21,7 +21,6 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
-import java.util.List;
import java.util.Objects;
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
@@ -50,6 +49,7 @@ import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.RegexpQuery;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Sort;
@@ -999,15 +999,7 @@ public class TestUnifiedHighlighterMTQ extends LuceneTestCase {
iw.close();
IndexSearcher searcher = newSearcher(ir);
- UnifiedHighlighter highlighter = new UnifiedHighlighter(searcher, indexAnalyzer) {
- @Override
- protected List<Query> preMultiTermQueryRewrite(Query query) {
- if (query instanceof MyWrapperSpanQuery) {
- return Collections.singletonList(((MyWrapperSpanQuery) query).originalQuery);
- }
- return null;
- }
- };
+ UnifiedHighlighter highlighter = new UnifiedHighlighter(searcher, indexAnalyzer);
int docId = searcher.search(new TermQuery(new Term("id", "id")), 1).scoreDocs[0].doc;
@@ -1052,6 +1044,11 @@ public class TestUnifiedHighlighterMTQ extends LuceneTestCase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ originalQuery.visit(visitor.getSubVisitor(BooleanClause.Occur.MUST, this));
+ }
+
+ @Override
public Query rewrite(IndexReader reader) throws IOException {
Query newOriginalQuery = originalQuery.rewrite(reader);
if (newOriginalQuery != originalQuery) {
diff --git a/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterStrictPhrases.java b/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterStrictPhrases.java
index a6d5d01..4c05e1b 100644
--- a/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterStrictPhrases.java
+++ b/lucene/highlighter/src/test/org/apache/lucene/search/uhighlight/TestUnifiedHighlighterStrictPhrases.java
@@ -42,6 +42,7 @@ import org.apache.lucene.search.MultiPhraseQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Sort;
@@ -588,6 +589,11 @@ public class TestUnifiedHighlighterStrictPhrases extends LuceneTestCase {
public int hashCode() {
return wrapped.hashCode();
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ wrapped.visit(visitor);
+ }
}
// Ported from LUCENE-5455 (fixed in LUCENE-8121). Also see LUCENE-2287.
diff --git a/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/FieldQueryTest.java b/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/FieldQueryTest.java
index eb888f6..135d8a6 100644
--- a/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/FieldQueryTest.java
+++ b/lucene/highlighter/src/test/org/apache/lucene/search/vectorhighlight/FieldQueryTest.java
@@ -15,6 +15,7 @@
* limitations under the License.
*/
package org.apache.lucene.search.vectorhighlight;
+
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
@@ -29,6 +30,7 @@ import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.RegexpQuery;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TermRangeQuery;
@@ -926,6 +928,12 @@ public class FieldQueryTest extends AbstractTestCase {
public String toString(String field) {
return "DummyQuery";
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
@Override
public boolean equals(Object o) {
throw new AssertionError();
diff --git a/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsQuery.java
index 8247f81..6bfdd1b 100644
--- a/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsQuery.java
+++ b/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsQuery.java
@@ -17,7 +17,6 @@
package org.apache.lucene.search.join;
import java.io.IOException;
-import java.util.Set;
import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.LeafReaderContext;
@@ -29,6 +28,7 @@ import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TwoPhaseIterator;
import org.apache.lucene.search.Weight;
@@ -61,6 +61,11 @@ final class GlobalOrdinalsQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, org.apache.lucene.search.ScoreMode scoreMode, float boost) throws IOException {
if (searcher.getTopReaderContext().id() != indexReaderContextId) {
throw new IllegalStateException("Creating the weight against a different index reader than this query has been built for.");
@@ -108,9 +113,6 @@ final class GlobalOrdinalsQuery extends Query {
}
@Override
- public void extractTerms(Set<Term> terms) {}
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
SortedDocValues values = DocValues.getSorted(context.reader(), joinField);
if (values == null) {
diff --git a/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsWithScoreQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsWithScoreQuery.java
index cdcf070..4cdf59b 100644
--- a/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsWithScoreQuery.java
+++ b/lucene/join/src/java/org/apache/lucene/search/join/GlobalOrdinalsWithScoreQuery.java
@@ -17,7 +17,6 @@
package org.apache.lucene.search.join;
import java.io.IOException;
-import java.util.Set;
import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.LeafReaderContext;
@@ -29,6 +28,7 @@ import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.FilterWeight;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TwoPhaseIterator;
import org.apache.lucene.search.Weight;
@@ -66,6 +66,11 @@ final class GlobalOrdinalsWithScoreQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, org.apache.lucene.search.ScoreMode scoreMode, float boost) throws IOException {
if (searcher.getTopReaderContext().id() != indexReaderContextId) {
throw new IllegalStateException("Creating the weight against a different index reader than this query has been built for.");
@@ -126,9 +131,6 @@ final class GlobalOrdinalsWithScoreQuery extends Query {
}
@Override
- public void extractTerms(Set<Term> terms) {}
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
SortedDocValues values = DocValues.getSorted(context.reader(), joinField);
if (values == null) {
diff --git a/lucene/join/src/java/org/apache/lucene/search/join/ParentChildrenBlockJoinQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/ParentChildrenBlockJoinQuery.java
index 7ce1c29..1108a49 100644
--- a/lucene/join/src/java/org/apache/lucene/search/join/ParentChildrenBlockJoinQuery.java
+++ b/lucene/join/src/java/org/apache/lucene/search/join/ParentChildrenBlockJoinQuery.java
@@ -18,16 +18,15 @@
package org.apache.lucene.search.join;
import java.io.IOException;
-import java.util.Set;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.ReaderUtil;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
import org.apache.lucene.util.BitSet;
@@ -84,6 +83,11 @@ public class ParentChildrenBlockJoinQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
+ @Override
public Query rewrite(IndexReader reader) throws IOException {
final Query childRewrite = childQuery.rewrite(reader);
if (childRewrite != childQuery) {
@@ -100,11 +104,6 @@ public class ParentChildrenBlockJoinQuery extends Query {
return new Weight(this) {
@Override
- public void extractTerms(Set<Term> terms) {
- childWeight.extractTerms(terms);
- }
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
return Explanation.noMatch("Not implemented, use ToParentBlockJoinQuery explain why a document matched");
}
diff --git a/lucene/join/src/java/org/apache/lucene/search/join/PointInSetIncludingScoreQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/PointInSetIncludingScoreQuery.java
index 80810e2..9b31e34 100644
--- a/lucene/join/src/java/org/apache/lucene/search/join/PointInSetIncludingScoreQuery.java
+++ b/lucene/join/src/java/org/apache/lucene/search/join/PointInSetIncludingScoreQuery.java
@@ -21,7 +21,6 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-import java.util.Set;
import java.util.function.BiFunction;
import org.apache.lucene.document.DoublePoint;
@@ -36,12 +35,12 @@ import org.apache.lucene.index.PointValues.IntersectVisitor;
import org.apache.lucene.index.PointValues.Relation;
import org.apache.lucene.index.PrefixCodedTerms;
import org.apache.lucene.index.PrefixCodedTerms.TermIterator;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.PointInSetQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
import org.apache.lucene.util.BitSetIterator;
@@ -120,14 +119,17 @@ abstract class PointInSetIncludingScoreQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public final Weight createWeight(IndexSearcher searcher, org.apache.lucene.search.ScoreMode scoreMode, float boost) throws IOException {
return new Weight(this) {
@Override
- public void extractTerms(Set<Term> terms) {
- }
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
Scorer scorer = scorer(context);
if (scorer != null) {
diff --git a/lucene/join/src/java/org/apache/lucene/search/join/TermsIncludingScoreQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/TermsIncludingScoreQuery.java
index 43ddd52..2466609 100644
--- a/lucene/join/src/java/org/apache/lucene/search/join/TermsIncludingScoreQuery.java
+++ b/lucene/join/src/java/org/apache/lucene/search/join/TermsIncludingScoreQuery.java
@@ -19,17 +19,16 @@ package org.apache.lucene.search.join;
import java.io.IOException;
import java.util.Locale;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.PostingsEnum;
-import org.apache.lucene.index.Term;
import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
import org.apache.lucene.util.BitSetIterator;
@@ -72,6 +71,13 @@ class TermsIncludingScoreQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(toField)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public boolean equals(Object other) {
return sameClassAs(other) &&
equalsTo(getClass().cast(other));
@@ -100,9 +106,6 @@ class TermsIncludingScoreQuery extends Query {
return new Weight(TermsIncludingScoreQuery.this) {
@Override
- public void extractTerms(Set<Term> terms) {}
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
Terms terms = context.reader().terms(toField);
if (terms != null) {
diff --git a/lucene/join/src/java/org/apache/lucene/search/join/TermsQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/TermsQuery.java
index 3ff0a5c..53b9c40 100644
--- a/lucene/join/src/java/org/apache/lucene/search/join/TermsQuery.java
+++ b/lucene/join/src/java/org/apache/lucene/search/join/TermsQuery.java
@@ -24,6 +24,7 @@ import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.util.AttributeSource;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefHash;
@@ -60,6 +61,11 @@ class TermsQuery extends MultiTermQuery {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
+ @Override
protected TermsEnum getTermsEnum(Terms terms, AttributeSource atts) throws IOException {
if (this.terms.size() == 0) {
return TermsEnum.EMPTY;
diff --git a/lucene/join/src/java/org/apache/lucene/search/join/ToChildBlockJoinQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/ToChildBlockJoinQuery.java
index ff8059c..11cc786 100644
--- a/lucene/join/src/java/org/apache/lucene/search/join/ToChildBlockJoinQuery.java
+++ b/lucene/join/src/java/org/apache/lucene/search/join/ToChildBlockJoinQuery.java
@@ -20,13 +20,15 @@ import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Locale;
+
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.search.FilterWeight;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Explanation;
+import org.apache.lucene.search.FilterWeight;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
import org.apache.lucene.util.BitSet;
@@ -65,6 +67,11 @@ public class ToChildBlockJoinQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, org.apache.lucene.search.ScoreMode scoreMode, float boost) throws IOException {
return new ToChildBlockJoinWeight(this, parentQuery.createWeight(searcher, scoreMode, boost), parentsFilter, scoreMode.needsScores());
}
diff --git a/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java b/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java
index 03bb5b9..c42cf39 100644
--- a/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java
+++ b/lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java
@@ -31,6 +31,7 @@ import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Matches;
import org.apache.lucene.search.MatchesUtils;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.ScorerSupplier;
import org.apache.lucene.search.TwoPhaseIterator;
@@ -86,6 +87,11 @@ public class ToParentBlockJoinQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, org.apache.lucene.search.ScoreMode weightScoreMode, float boost) throws IOException {
return new BlockJoinWeight(this, childQuery.createWeight(searcher, weightScoreMode, boost), parentsFilter, weightScoreMode.needsScores() ? scoreMode : ScoreMode.None);
}
diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java b/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java
index 1eb1adb..a82d33e 100644
--- a/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java
+++ b/lucene/join/src/test/org/apache/lucene/search/join/TestBlockJoin.java
@@ -20,15 +20,14 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import com.carrotsearch.randomizedtesting.generators.RandomPicks;
import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
@@ -63,8 +62,6 @@ import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.TestUtil;
-import com.carrotsearch.randomizedtesting.generators.RandomPicks;
-
public class TestBlockJoin extends LuceneTestCase {
// One resume...
@@ -93,34 +90,6 @@ public class TestBlockJoin extends LuceneTestCase {
return job;
}
- public void testExtractTerms() throws Exception {
- TermQuery termQuery = new TermQuery(new Term("field", "value"));
- QueryBitSetProducer bitSetProducer = new QueryBitSetProducer(new MatchNoDocsQuery());
- ToParentBlockJoinQuery toParentBlockJoinQuery = new ToParentBlockJoinQuery(termQuery, bitSetProducer, ScoreMode.None);
- ToChildBlockJoinQuery toChildBlockJoinQuery = new ToChildBlockJoinQuery(toParentBlockJoinQuery, bitSetProducer);
-
- Directory directory = newDirectory();
- final IndexWriter w = new IndexWriter(directory, new IndexWriterConfig(new MockAnalyzer(random())));
- w.close();
- IndexReader indexReader = DirectoryReader.open(directory);
- IndexSearcher indexSearcher = new IndexSearcher(indexReader);
-
- Weight weight = toParentBlockJoinQuery.createWeight(indexSearcher, org.apache.lucene.search.ScoreMode.COMPLETE_NO_SCORES, 1f);
- Set<Term> terms = new HashSet<>();
- weight.extractTerms(terms);
- Term[] termArr =terms.toArray(new Term[0]);
- assertEquals(1, termArr.length);
-
- weight = toChildBlockJoinQuery.createWeight(indexSearcher, org.apache.lucene.search.ScoreMode.COMPLETE_NO_SCORES, 1f);
- terms = new HashSet<>();
- weight.extractTerms(terms);
- termArr =terms.toArray(new Term[0]);
- assertEquals(1, termArr.length);
-
- indexReader.close();
- directory.close();
- }
-
public void testEmptyChildFilter() throws Exception {
final Directory dir = newDirectory();
final IndexWriterConfig config = new IndexWriterConfig(new MockAnalyzer(random()));
diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java b/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java
index 59309fa..8e5f35d 100644
--- a/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java
+++ b/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java
@@ -32,6 +32,8 @@ import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
+import com.carrotsearch.randomizedtesting.generators.RandomNumbers;
+import com.carrotsearch.randomizedtesting.generators.RandomPicks;
import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.analysis.MockTokenizer;
import org.apache.lucene.document.Document;
@@ -77,9 +79,6 @@ import org.apache.lucene.util.TestUtil;
import org.apache.lucene.util.packed.PackedInts;
import org.junit.Test;
-import com.carrotsearch.randomizedtesting.generators.RandomNumbers;
-import com.carrotsearch.randomizedtesting.generators.RandomPicks;
-
public class TestJoinUtil extends LuceneTestCase {
public void testSimple() throws Exception {
@@ -521,10 +520,6 @@ public class TestJoinUtil extends LuceneTestCase {
return new Weight(this) {
@Override
- public void extractTerms(Set<Term> terms) {
- }
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
return null;
}
@@ -557,7 +552,12 @@ public class TestJoinUtil extends LuceneTestCase {
};
}
- @Override
+ @Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
+ @Override
public String toString(String field) {
return fieldQuery.toString(field);
}
diff --git a/lucene/misc/src/test/org/apache/lucene/search/TestDiversifiedTopDocsCollector.java b/lucene/misc/src/test/org/apache/lucene/search/TestDiversifiedTopDocsCollector.java
index db17a90..a65dac9 100644
--- a/lucene/misc/src/test/org/apache/lucene/search/TestDiversifiedTopDocsCollector.java
+++ b/lucene/misc/src/test/org/apache/lucene/search/TestDiversifiedTopDocsCollector.java
@@ -19,7 +19,6 @@ package org.apache.lucene.search;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
-import java.util.Set;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
@@ -478,6 +477,11 @@ public class TestDiversifiedTopDocsCollector extends LuceneTestCase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ query.visit(visitor);
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
if (scoreMode.needsScores() == false) {
return query.createWeight(searcher, scoreMode, boost);
@@ -520,12 +524,7 @@ public class TestDiversifiedTopDocsCollector extends LuceneTestCase {
}
};
}
-
- @Override
- public void extractTerms(Set<Term> terms) {
- inner.extractTerms(terms);
- }
-
+
@Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
Scorer s = scorer(context);
diff --git a/lucene/queries/src/java/org/apache/lucene/queries/CommonTermsQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/CommonTermsQuery.java
index 10c232e..5c361cf 100644
--- a/lucene/queries/src/java/org/apache/lucene/queries/CommonTermsQuery.java
+++ b/lucene/queries/src/java/org/apache/lucene/queries/CommonTermsQuery.java
@@ -33,6 +33,7 @@ import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.TermQuery;
/**
@@ -129,7 +130,16 @@ public class CommonTermsQuery extends Query {
collectTermStates(reader, leaves, contextArray, queryTerms);
return buildQuery(maxDoc, contextArray, queryTerms);
}
-
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ Term[] selectedTerms = terms.stream().filter(t -> visitor.acceptField(t.field())).toArray(Term[]::new);
+ if (selectedTerms.length > 0) {
+ QueryVisitor v = visitor.getSubVisitor(Occur.SHOULD, this);
+ v.consumeTerms(this, selectedTerms);
+ }
+ }
+
protected int calcLowFreqMinimumNumberShouldMatch(int numOptional) {
return minNrShouldMatch(lowFreqMinNrShouldMatch, numOptional);
}
diff --git a/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionMatchQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionMatchQuery.java
index 38cf3f6..39a51c1 100644
--- a/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionMatchQuery.java
+++ b/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionMatchQuery.java
@@ -29,6 +29,7 @@ import org.apache.lucene.search.DoubleValues;
import org.apache.lucene.search.DoubleValuesSource;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TwoPhaseIterator;
@@ -62,6 +63,11 @@ public final class FunctionMatchQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
DoubleValuesSource vs = source.rewrite(searcher);
return new ConstantScoreWeight(this, boost) {
diff --git a/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionQuery.java
index f996306..c804523 100644
--- a/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionQuery.java
+++ b/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionQuery.java
@@ -18,15 +18,14 @@ package org.apache.lucene.queries.function;
import java.io.IOException;
import java.util.Map;
-import java.util.Set;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
@@ -68,9 +67,6 @@ public class FunctionQuery extends Query {
}
@Override
- public void extractTerms(Set<Term> terms) {}
-
- @Override
public Scorer scorer(LeafReaderContext context) throws IOException {
return new AllScorer(context, this, boost);
}
@@ -86,6 +82,11 @@ public class FunctionQuery extends Query {
}
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
protected class AllScorer extends Scorer {
final IndexReader reader;
final FunctionWeight weight;
@@ -150,7 +151,6 @@ public class FunctionQuery extends Query {
return new FunctionQuery.FunctionWeight(searcher, boost);
}
-
/** Prints a user-readable version of this query. */
@Override
public String toString(String field)
diff --git a/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionRangeQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionRangeQuery.java
index 315f650..f72e12b 100644
--- a/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionRangeQuery.java
+++ b/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionRangeQuery.java
@@ -19,13 +19,12 @@ package org.apache.lucene.queries.function;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Weight;
@@ -115,6 +114,11 @@ public class FunctionRangeQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
return new FunctionRangeWeight(searcher);
}
@@ -130,11 +134,6 @@ public class FunctionRangeQuery extends Query {
}
@Override
- public void extractTerms(Set<Term> terms) {
- //none
- }
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
FunctionValues functionValues = valueSource.getValues(vsContext, context);
//note: by using ValueSourceScorer directly, we avoid calling scorer.advance(doc) and checking if true,
diff --git a/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionScoreQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionScoreQuery.java
index 29d6dd9..2ba77e2 100644
--- a/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionScoreQuery.java
+++ b/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionScoreQuery.java
@@ -19,11 +19,10 @@ package org.apache.lucene.queries.function;
import java.io.IOException;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.DoubleValues;
import org.apache.lucene.search.DoubleValuesSource;
import org.apache.lucene.search.Explanation;
@@ -31,6 +30,7 @@ import org.apache.lucene.search.FilterScorer;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Matches;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
@@ -120,6 +120,11 @@ public final class FunctionScoreQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ in.visit(visitor.getSubVisitor(BooleanClause.Occur.MUST, this));
+ }
+
+ @Override
public String toString(String field) {
return "FunctionScoreQuery(" + in.toString(field) + ", scored by " + source.toString() + ")";
}
@@ -152,11 +157,6 @@ public final class FunctionScoreQuery extends Query {
}
@Override
- public void extractTerms(Set<Term> terms) {
- this.inner.extractTerms(terms);
- }
-
- @Override
public Matches matches(LeafReaderContext context, int doc) throws IOException {
return inner.matches(context, doc);
}
diff --git a/lucene/queries/src/java/org/apache/lucene/queries/mlt/MoreLikeThisQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/mlt/MoreLikeThisQuery.java
index 9f3310c..976660e 100644
--- a/lucene/queries/src/java/org/apache/lucene/queries/mlt/MoreLikeThisQuery.java
+++ b/lucene/queries/src/java/org/apache/lucene/queries/mlt/MoreLikeThisQuery.java
@@ -16,17 +16,18 @@
*/
package org.apache.lucene.queries.mlt;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.Set;
+
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.Arrays;
-import java.util.Set;
-import java.util.Objects;
+import org.apache.lucene.search.QueryVisitor;
/**
* A simple wrapper for MoreLikeThis for use in scenarios where a Query object is required eg
@@ -179,4 +180,9 @@ public class MoreLikeThisQuery extends Query {
Arrays.equals(moreLikeFields, other.moreLikeFields) &&
Objects.equals(stopWords, other.stopWords);
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
}
diff --git a/lucene/queries/src/java/org/apache/lucene/queries/payloads/PayloadScoreQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/payloads/PayloadScoreQuery.java
index bd5d927..f2bf4e7 100644
--- a/lucene/queries/src/java/org/apache/lucene/queries/payloads/PayloadScoreQuery.java
+++ b/lucene/queries/src/java/org/apache/lucene/queries/payloads/PayloadScoreQuery.java
@@ -19,17 +19,18 @@ package org.apache.lucene.queries.payloads;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.PostingsEnum;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermStates;
+import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.LeafSimScorer;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.spans.FilterSpans;
import org.apache.lucene.search.spans.SpanCollector;
@@ -86,6 +87,11 @@ public class PayloadScoreQuery extends SpanQuery {
return super.rewrite(reader);
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ wrappedQuery.visit(visitor.getSubVisitor(BooleanClause.Occur.MUST, this));
+ }
+
@Override
public String toString(String field) {
@@ -160,11 +166,6 @@ public class PayloadScoreQuery extends SpanQuery {
}
@Override
- public void extractTerms(Set<Term> terms) {
- innerWeight.extractTerms(terms);
- }
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
PayloadSpanScorer scorer = (PayloadSpanScorer)scorer(context);
if (scorer == null || scorer.iterator().advance(doc) != doc)
diff --git a/lucene/queries/src/java/org/apache/lucene/queries/payloads/SpanPayloadCheckQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/payloads/SpanPayloadCheckQuery.java
index a9d3bfb..30d18f0 100644
--- a/lucene/queries/src/java/org/apache/lucene/queries/payloads/SpanPayloadCheckQuery.java
+++ b/lucene/queries/src/java/org/apache/lucene/queries/payloads/SpanPayloadCheckQuery.java
@@ -15,11 +15,11 @@
* limitations under the License.
*/
package org.apache.lucene.queries.payloads;
+
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
@@ -27,9 +27,11 @@ import org.apache.lucene.index.PostingsEnum;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermStates;
import org.apache.lucene.index.Terms;
+import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.LeafSimScorer;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.spans.FilterSpans;
import org.apache.lucene.search.spans.FilterSpans.AcceptStatus;
@@ -77,6 +79,13 @@ public class SpanPayloadCheckQuery extends SpanQuery {
return super.rewrite(reader);
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(match.getField())) {
+ match.visit(visitor.getSubVisitor(BooleanClause.Occur.MUST, this));
+ }
+ }
+
/**
* Weight that pulls its Spans using a PayloadSpanCollector
*/
@@ -90,11 +99,6 @@ public class SpanPayloadCheckQuery extends SpanQuery {
}
@Override
- public void extractTerms(Set<Term> terms) {
- matchWeight.extractTerms(terms);
- }
-
- @Override
public void extractTermStates(Map<Term, TermStates> contexts) {
matchWeight.extractTermStates(contexts);
}
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/complexPhrase/ComplexPhraseQueryParser.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/complexPhrase/ComplexPhraseQueryParser.java
index ffe0066..9a4043d 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/complexPhrase/ComplexPhraseQueryParser.java
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/complexPhrase/ComplexPhraseQueryParser.java
@@ -36,6 +36,7 @@ import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.MultiTermQuery.RewriteMethod;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.SynonymQuery;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.spans.SpanBoostQuery;
@@ -254,6 +255,11 @@ public class ComplexPhraseQueryParser extends QueryParser {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
+ @Override
public Query rewrite(IndexReader reader) throws IOException {
final Query contents = this.contents[0];
// ArrayList spanClauses = new ArrayList();
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/query/DistanceRewriteQuery.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/query/DistanceRewriteQuery.java
index 1972a8e..adbbd0a 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/query/DistanceRewriteQuery.java
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/query/DistanceRewriteQuery.java
@@ -15,10 +15,12 @@
* limitations under the License.
*/
package org.apache.lucene.queryparser.surround.query;
+
import java.io.IOException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
class DistanceRewriteQuery extends RewriteQuery<DistanceQuery> {
@@ -33,5 +35,11 @@ class DistanceRewriteQuery extends RewriteQuery<DistanceQuery> {
public Query rewrite(IndexReader reader) throws IOException {
return srndQuery.getSpanNearQuery(reader, fieldName, qf);
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ // TODO implement this
+ visitor.visitLeaf(this);
+ }
}
diff --git a/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/query/SimpleTermRewriteQuery.java b/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/query/SimpleTermRewriteQuery.java
index 3e0e4aa..50203a8 100644
--- a/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/query/SimpleTermRewriteQuery.java
+++ b/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/query/SimpleTermRewriteQuery.java
@@ -15,15 +15,17 @@
* limitations under the License.
*/
package org.apache.lucene.queryparser.surround.query;
+
import java.io.IOException;
-import java.util.List;
import java.util.ArrayList;
+import java.util.List;
import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
-import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.index.Term;
+import org.apache.lucene.search.QueryVisitor;
class SimpleTermRewriteQuery extends RewriteQuery<SimpleTerm> {
@@ -50,5 +52,11 @@ class SimpleTermRewriteQuery extends RewriteQuery<SimpleTerm> {
/* luceneSubQueries all have default weight */
luceneSubQueries, BooleanClause.Occur.SHOULD); /* OR the subquery terms */
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ // TODO: implement this
+ visitor.visitLeaf(this);
+ }
}
diff --git a/lucene/queryparser/src/test/org/apache/lucene/queryparser/classic/TestMultiAnalyzer.java b/lucene/queryparser/src/test/org/apache/lucene/queryparser/classic/TestMultiAnalyzer.java
index 85a5f39..15dd3c5 100644
--- a/lucene/queryparser/src/test/org/apache/lucene/queryparser/classic/TestMultiAnalyzer.java
+++ b/lucene/queryparser/src/test/org/apache/lucene/queryparser/classic/TestMultiAnalyzer.java
@@ -19,12 +19,18 @@ package org.apache.lucene.queryparser.classic;
import java.io.IOException;
import java.util.Objects;
-import org.apache.lucene.analysis.*;
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.analysis.BaseTokenStreamTestCase;
+import org.apache.lucene.analysis.MockTokenizer;
+import org.apache.lucene.analysis.TokenFilter;
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
-import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.TypeAttribute;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
/**
* Test QueryParser's ability to deal with Analyzers that return more
@@ -263,7 +269,12 @@ public class TestMultiAnalyzer extends BaseTokenStreamTestCase {
return q.toString(f);
}
- @Override
+ @Override
+ public void visit(QueryVisitor visitor) {
+ q.visit(visitor);
+ }
+
+ @Override
public boolean equals(Object other) {
return sameClassAs(other) &&
Objects.equals(q, ((DumbQueryWrapper) other).q);
diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonShapeQuery.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonShapeQuery.java
index 538f4a3..124a7a7 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonShapeQuery.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonShapeQuery.java
@@ -31,6 +31,7 @@ import org.apache.lucene.search.ConstantScoreWeight;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.ScorerSupplier;
@@ -86,6 +87,13 @@ abstract class LatLonShapeQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public final Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
return new ConstantScoreWeight(this, boost) {
diff --git a/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/FuzzyLikeThisQuery.java b/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/FuzzyLikeThisQuery.java
index a7898f7..a0e1b5d 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/FuzzyLikeThisQuery.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/sandbox/queries/FuzzyLikeThisQuery.java
@@ -41,6 +41,7 @@ import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.FuzzyTermsEnum;
import org.apache.lucene.search.MaxNonCompetitiveBoostAttribute;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.similarities.ClassicSimilarity;
import org.apache.lucene.search.similarities.TFIDFSimilarity;
@@ -273,6 +274,11 @@ public class FuzzyLikeThisQuery extends Query
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
+ @Override
public Query rewrite(IndexReader reader) throws IOException
{
ScoreTermQueue q = new ScoreTermQueue(maxNumTerms);
@@ -330,7 +336,7 @@ public class FuzzyLikeThisQuery extends Query
// booleans with a minimum-should-match of NumFields-1?
return bq.build();
}
-
+
//Holds info for a fuzzy term variant - initially score is set to edit distance (for ranking best
// term variants) then is reset with IDF for use in ranking against all other
// terms/fields
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/BM25FQuery.java b/lucene/sandbox/src/java/org/apache/lucene/search/BM25FQuery.java
index 1a80351..080537b 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/BM25FQuery.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/BM25FQuery.java
@@ -223,6 +223,15 @@ public final class BM25FQuery extends Query {
return this;
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ Term[] selectedTerms = Arrays.stream(fieldTerms).filter(t -> visitor.acceptField(t.field())).toArray(Term[]::new);
+ if (selectedTerms.length > 0) {
+ QueryVisitor v = visitor.getSubVisitor(BooleanClause.Occur.SHOULD, this);
+ v.consumeTerms(this, selectedTerms);
+ }
+ }
+
private BooleanQuery rewriteToBoolean() {
// rewrite to a simple disjunction if the score is not needed.
BooleanQuery.Builder bq = new BooleanQuery.Builder();
@@ -291,11 +300,6 @@ public final class BM25FQuery extends Query {
}
@Override
- public void extractTerms(Set<Term> termSet) {
- termSet.addAll(Arrays.asList(fieldTerms));
- }
-
- @Override
public Matches matches(LeafReaderContext context, int doc) throws IOException {
Weight weight = searcher.rewrite(rewriteToBoolean()).createWeight(searcher, ScoreMode.COMPLETE, 1f);
return weight.matches(context, doc);
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/CoveringQuery.java b/lucene/sandbox/src/java/org/apache/lucene/search/CoveringQuery.java
index fd89888..5d5c8f8 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/CoveringQuery.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/CoveringQuery.java
@@ -21,12 +21,10 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
-import java.util.Set;
import java.util.stream.Collectors;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
/** A {@link Query} that allows to have a configurable number or required
* matches per document. This is typically useful in order to build queries
@@ -110,6 +108,14 @@ public final class CoveringQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ QueryVisitor v = visitor.getSubVisitor(BooleanClause.Occur.SHOULD, this);
+ for (Query query : queries) {
+ query.visit(v);
+ }
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
final List<Weight> weights = new ArrayList<>(queries.size());
for (Query query : queries) {
@@ -130,13 +136,6 @@ public final class CoveringQuery extends Query {
}
@Override
- public void extractTerms(Set<Term> terms) {
- for (Weight weight : weights) {
- weight.extractTerms(terms);
- }
- }
-
- @Override
public Matches matches(LeafReaderContext context, int doc) throws IOException {
LongValues minMatchValues = minimumNumberMatch.getValues(context, null);
if (minMatchValues.advanceExact(doc) == false) {
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesNumbersQuery.java b/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesNumbersQuery.java
index f018df4..cdfe23d 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesNumbersQuery.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesNumbersQuery.java
@@ -78,6 +78,13 @@ public class DocValuesNumbersQuery extends Query {
return 31 * classHash() + Objects.hash(field, numbers);
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
public String getField() {
return field;
}
@@ -129,4 +136,5 @@ public class DocValuesNumbersQuery extends Query {
};
}
+
}
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesTermsQuery.java b/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesTermsQuery.java
index 8ca53b7..ef67b02 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesTermsQuery.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/DocValuesTermsQuery.java
@@ -26,9 +26,9 @@ import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.PrefixCodedTerms;
+import org.apache.lucene.index.PrefixCodedTerms.TermIterator;
import org.apache.lucene.index.SortedSetDocValues;
import org.apache.lucene.index.Term;
-import org.apache.lucene.index.PrefixCodedTerms.TermIterator;
import org.apache.lucene.util.ArrayUtil;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.FixedBitSet;
@@ -165,6 +165,13 @@ public class DocValuesTermsQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
return new ConstantScoreWeight(this, boost) {
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java b/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java
index 81426a7..cd123af 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java
@@ -21,7 +21,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexReaderContext;
@@ -29,8 +28,8 @@ import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.PostingsEnum;
import org.apache.lucene.index.ReaderUtil;
import org.apache.lucene.index.Term;
-import org.apache.lucene.index.TermStates;
import org.apache.lucene.index.TermState;
+import org.apache.lucene.index.TermStates;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.search.spans.SpanNearQuery;
@@ -363,15 +362,6 @@ public class TermAutomatonQuery extends Query {
}
@Override
- public void extractTerms(Set<Term> terms) {
- for(BytesRef text : termToID.keySet()) {
- if (text != null) {
- terms.add(new Term(field, text));
- }
- }
- }
-
- @Override
public String toString() {
return "weight(" + TermAutomatonQuery.this + ")";
}
@@ -492,4 +482,15 @@ public class TermAutomatonQuery extends Query {
// TODO: we could maybe also rewrite to union of PhraseQuery (pull all finite strings) if it's "worth it"?
return this;
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field) == false) {
+ return;
+ }
+ QueryVisitor v = visitor.getSubVisitor(BooleanClause.Occur.SHOULD, this);
+ for (BytesRef term : termToID.keySet()) {
+ v.consumeTerms(this, new Term(field, term));
+ }
+ }
}
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/ConjunctionIntervalsSource.java b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/ConjunctionIntervalsSource.java
index ec4341d..123cc38 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/ConjunctionIntervalsSource.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/ConjunctionIntervalsSource.java
@@ -21,15 +21,15 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
-import java.util.Set;
import java.util.stream.Collectors;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.FilterMatchesIterator;
import org.apache.lucene.search.MatchesIterator;
import org.apache.lucene.search.MatchesUtils;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
class ConjunctionIntervalsSource extends IntervalsSource {
@@ -56,9 +56,11 @@ class ConjunctionIntervalsSource extends IntervalsSource {
}
@Override
- public void extractTerms(String field, Set<Term> terms) {
+ public void visit(String field, QueryVisitor visitor) {
+ Query parent = new IntervalQuery(field, this);
+ QueryVisitor v = visitor.getSubVisitor(BooleanClause.Occur.MUST, parent);
for (IntervalsSource source : subSources) {
- source.extractTerms(field, terms);
+ source.visit(field, v);
}
}
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/DifferenceIntervalsSource.java b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/DifferenceIntervalsSource.java
index 7289d04..f1d096c 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/DifferenceIntervalsSource.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/DifferenceIntervalsSource.java
@@ -19,11 +19,11 @@ package org.apache.lucene.search.intervals;
import java.io.IOException;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.MatchesIterator;
+import org.apache.lucene.search.QueryVisitor;
class DifferenceIntervalsSource extends IntervalsSource {
@@ -83,8 +83,10 @@ class DifferenceIntervalsSource extends IntervalsSource {
}
@Override
- public void extractTerms(String field, Set<Term> terms) {
- minuend.extractTerms(field, terms);
+ public void visit(String field, QueryVisitor visitor) {
+ IntervalQuery q = new IntervalQuery(field, this);
+ minuend.visit(field, visitor.getSubVisitor(BooleanClause.Occur.MUST, q));
+ subtrahend.visit(field, visitor.getSubVisitor(BooleanClause.Occur.MUST_NOT, q));
}
@Override
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/DisjunctionIntervalsSource.java b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/DisjunctionIntervalsSource.java
index b280885..f37dcb6 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/DisjunctionIntervalsSource.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/DisjunctionIntervalsSource.java
@@ -21,14 +21,15 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
-import java.util.Set;
import java.util.stream.Collectors;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.MatchesIterator;
import org.apache.lucene.search.MatchesUtils;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.util.PriorityQueue;
class DisjunctionIntervalsSource extends IntervalsSource {
@@ -84,9 +85,11 @@ class DisjunctionIntervalsSource extends IntervalsSource {
}
@Override
- public void extractTerms(String field, Set<Term> terms) {
+ public void visit(String field, QueryVisitor visitor) {
+ Query parent = new IntervalQuery(field, this);
+ QueryVisitor v = visitor.getSubVisitor(BooleanClause.Occur.SHOULD, parent);
for (IntervalsSource source : subSources) {
- source.extractTerms(field, terms);
+ source.visit(field, v);
}
}
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/ExtendedIntervalsSource.java b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/ExtendedIntervalsSource.java
index 864a4b5..41a8829 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/ExtendedIntervalsSource.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/ExtendedIntervalsSource.java
@@ -19,11 +19,10 @@ package org.apache.lucene.search.intervals;
import java.io.IOException;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.MatchesIterator;
+import org.apache.lucene.search.QueryVisitor;
class ExtendedIntervalsSource extends IntervalsSource {
@@ -57,8 +56,8 @@ class ExtendedIntervalsSource extends IntervalsSource {
}
@Override
- public void extractTerms(String field, Set<Term> terms) {
- source.extractTerms(field, terms);
+ public void visit(String field, QueryVisitor visitor) {
+ source.visit(field, visitor);
}
@Override
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/FilteredIntervalsSource.java b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/FilteredIntervalsSource.java
index c2b4d60..b334129 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/FilteredIntervalsSource.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/FilteredIntervalsSource.java
@@ -19,11 +19,10 @@ package org.apache.lucene.search.intervals;
import java.io.IOException;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.MatchesIterator;
+import org.apache.lucene.search.QueryVisitor;
/**
* An IntervalsSource that filters the intervals from another IntervalsSource
@@ -83,8 +82,8 @@ public abstract class FilteredIntervalsSource extends IntervalsSource {
}
@Override
- public void extractTerms(String field, Set<Term> terms) {
- in.extractTerms(field, terms);
+ public void visit(String field, QueryVisitor visitor) {
+ in.visit(field, visitor);
}
@Override
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/FixedFieldIntervalsSource.java b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/FixedFieldIntervalsSource.java
index 7776a2b..ab24ee3 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/FixedFieldIntervalsSource.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/FixedFieldIntervalsSource.java
@@ -19,11 +19,10 @@ package org.apache.lucene.search.intervals;
import java.io.IOException;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.MatchesIterator;
+import org.apache.lucene.search.QueryVisitor;
class FixedFieldIntervalsSource extends IntervalsSource {
@@ -46,8 +45,8 @@ class FixedFieldIntervalsSource extends IntervalsSource {
}
@Override
- public void extractTerms(String field, Set<Term> terms) {
- source.extractTerms(this.field, terms);
+ public void visit(String field, QueryVisitor visitor) {
+ source.visit(this.field, visitor);
}
@Override
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/IntervalQuery.java b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/IntervalQuery.java
index 62fe067..6b6450d 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/IntervalQuery.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/IntervalQuery.java
@@ -19,10 +19,8 @@ package org.apache.lucene.search.intervals;
import java.io.IOException;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.FilterMatchesIterator;
import org.apache.lucene.search.IndexSearcher;
@@ -30,6 +28,7 @@ import org.apache.lucene.search.Matches;
import org.apache.lucene.search.MatchesIterator;
import org.apache.lucene.search.MatchesUtils;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
@@ -121,6 +120,13 @@ public final class IntervalQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ intervalsSource.visit(field, visitor);
+ }
+ }
+
+ @Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@@ -146,11 +152,6 @@ public final class IntervalQuery extends Query {
}
@Override
- public void extractTerms(Set<Term> terms) {
- intervalsSource.extractTerms(field, terms);
- }
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
IntervalScorer scorer = (IntervalScorer) scorer(context);
if (scorer != null) {
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/IntervalsSource.java b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/IntervalsSource.java
index dc4161f..1c49d24 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/IntervalsSource.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/IntervalsSource.java
@@ -18,11 +18,10 @@
package org.apache.lucene.search.intervals;
import java.io.IOException;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.MatchesIterator;
+import org.apache.lucene.search.QueryVisitor;
/**
* A helper class for {@link IntervalQuery} that provides an {@link IntervalIterator}
@@ -56,11 +55,9 @@ public abstract class IntervalsSource {
public abstract MatchesIterator matches(String field, LeafReaderContext ctx, int doc) throws IOException;
/**
- * Expert: collect {@link Term} objects from this source
- * @param field the field to be scored
- * @param terms a {@link Set} which terms should be added to
+ * Expert: visit the tree of sources
*/
- public abstract void extractTerms(String field, Set<Term> terms);
+ public abstract void visit(String field, QueryVisitor visitor);
/**
* Return the minimum possible width of an interval returned by this source
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/MinimumShouldMatchIntervalsSource.java b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/MinimumShouldMatchIntervalsSource.java
index 1935c62..a06c478 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/MinimumShouldMatchIntervalsSource.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/MinimumShouldMatchIntervalsSource.java
@@ -25,15 +25,15 @@ import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
-import java.util.Set;
import java.util.stream.Collectors;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.MatchesIterator;
import org.apache.lucene.search.MatchesUtils;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.util.PriorityQueue;
class MinimumShouldMatchIntervalsSource extends IntervalsSource {
@@ -85,9 +85,11 @@ class MinimumShouldMatchIntervalsSource extends IntervalsSource {
}
@Override
- public void extractTerms(String field, Set<Term> terms) {
+ public void visit(String field, QueryVisitor visitor) {
+ Query parent = new IntervalQuery(field, this);
+ QueryVisitor v = visitor.getSubVisitor(BooleanClause.Occur.SHOULD, parent);
for (IntervalsSource source : sources) {
- source.extractTerms(field, terms);
+ source.visit(field, v);
}
}
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/MultiTermIntervalsSource.java b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/MultiTermIntervalsSource.java
index 7689d1d..1ee52d4 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/MultiTermIntervalsSource.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/MultiTermIntervalsSource.java
@@ -21,14 +21,13 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.search.MatchesIterator;
import org.apache.lucene.search.MatchesUtils;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.automaton.CompiledAutomaton;
@@ -89,7 +88,7 @@ class MultiTermIntervalsSource extends IntervalsSource {
}
@Override
- public void extractTerms(String field, Set<Term> terms) {
+ public void visit(String field, QueryVisitor visitor) {
}
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/OffsetIntervalsSource.java b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/OffsetIntervalsSource.java
index b2ca302..078c64b 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/OffsetIntervalsSource.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/OffsetIntervalsSource.java
@@ -19,11 +19,10 @@ package org.apache.lucene.search.intervals;
import java.io.IOException;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.MatchesIterator;
+import org.apache.lucene.search.QueryVisitor;
/**
* Tracks a reference intervals source, and produces a pseudo-interval that appears
@@ -144,8 +143,8 @@ class OffsetIntervalsSource extends IntervalsSource {
}
@Override
- public void extractTerms(String field, Set<Term> terms) {
- in.extractTerms(field, terms);
+ public void visit(String field, QueryVisitor visitor) {
+ in.visit(field, visitor);
}
@Override
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/TermIntervalsSource.java b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/TermIntervalsSource.java
index 4539d2f..3d6fe20 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/intervals/TermIntervalsSource.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/intervals/TermIntervalsSource.java
@@ -19,7 +19,6 @@ package org.apache.lucene.search.intervals;
import java.io.IOException;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.codecs.lucene50.Lucene50PostingsFormat;
import org.apache.lucene.codecs.lucene50.Lucene50PostingsReader;
@@ -32,6 +31,7 @@ import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.MatchesIterator;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.TwoPhaseIterator;
import org.apache.lucene.util.BytesRef;
@@ -227,8 +227,8 @@ class TermIntervalsSource extends IntervalsSource {
}
@Override
- public void extractTerms(String field, Set<Term> terms) {
- terms.add(new Term(field, term));
+ public void visit(String field, QueryVisitor visitor) {
+ visitor.consumeTerms(new IntervalQuery(field, this), new Term(field, term));
}
/** A guess of
diff --git a/lucene/sandbox/src/test/org/apache/lucene/sandbox/queries/FuzzyLikeThisQueryTest.java b/lucene/sandbox/src/test/org/apache/lucene/sandbox/queries/FuzzyLikeThisQueryTest.java
index ead2720..95c6cca 100644
--- a/lucene/sandbox/src/test/org/apache/lucene/sandbox/queries/FuzzyLikeThisQueryTest.java
+++ b/lucene/sandbox/src/test/org/apache/lucene/sandbox/queries/FuzzyLikeThisQueryTest.java
@@ -16,6 +16,9 @@
*/
package org.apache.lucene.sandbox.queries;
+import java.io.IOException;
+import java.util.HashSet;
+
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.MockAnalyzer;
import org.apache.lucene.document.Document;
@@ -25,16 +28,13 @@ import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreDoc;
-import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.IOUtils;
import org.apache.lucene.util.LuceneTestCase;
-import java.io.IOException;
-import java.util.HashSet;
-
public class FuzzyLikeThisQueryTest extends LuceneTestCase {
private Directory directory;
private IndexSearcher searcher;
@@ -81,7 +81,7 @@ public class FuzzyLikeThisQueryTest extends LuceneTestCase {
flt.addTerms("smith", "name", 2, 1);
Query q = flt.rewrite(searcher.getIndexReader());
HashSet<Term> queryTerms = new HashSet<>();
- searcher.createWeight(q, ScoreMode.COMPLETE, 1f).extractTerms(queryTerms);
+ q.visit(QueryVisitor.termCollector(queryTerms));
assertTrue("Should have variant smythe", queryTerms.contains(new Term("name", "smythe")));
assertTrue("Should have variant smith", queryTerms.contains(new Term("name", "smith")));
assertTrue("Should have variant smyth", queryTerms.contains(new Term("name", "smyth")));
@@ -98,7 +98,7 @@ public class FuzzyLikeThisQueryTest extends LuceneTestCase {
flt.addTerms("jonathin smoth", "name", 2, 1);
Query q = flt.rewrite(searcher.getIndexReader());
HashSet<Term> queryTerms = new HashSet<>();
- searcher.createWeight(q, ScoreMode.COMPLETE, 1f).extractTerms(queryTerms);
+ q.visit(QueryVisitor.termCollector(queryTerms));
assertTrue("Should have variant jonathan", queryTerms.contains(new Term("name", "jonathan")));
assertTrue("Should have variant smith", queryTerms.contains(new Term("name", "smith")));
TopDocs topDocs = searcher.search(flt, 1);
@@ -116,7 +116,7 @@ public class FuzzyLikeThisQueryTest extends LuceneTestCase {
// don't fail here just because the field doesn't exits
Query q = flt.rewrite(searcher.getIndexReader());
HashSet<Term> queryTerms = new HashSet<>();
- searcher.createWeight(q, ScoreMode.COMPLETE, 1f).extractTerms(queryTerms);
+ q.visit(QueryVisitor.termCollector(queryTerms));
assertTrue("Should have variant jonathan", queryTerms.contains(new Term("name", "jonathan")));
assertTrue("Should have variant smith", queryTerms.contains(new Term("name", "smith")));
TopDocs topDocs = searcher.search(flt, 1);
@@ -133,7 +133,7 @@ public class FuzzyLikeThisQueryTest extends LuceneTestCase {
flt.addTerms("fernando smith", "name", 2, 1);
Query q = flt.rewrite(searcher.getIndexReader());
HashSet<Term> queryTerms = new HashSet<>();
- searcher.createWeight(q, ScoreMode.COMPLETE, 1f).extractTerms(queryTerms);
+ q.visit(QueryVisitor.termCollector(queryTerms));
assertTrue("Should have variant smith", queryTerms.contains(new Term("name", "smith")));
TopDocs topDocs = searcher.search(flt, 1);
ScoreDoc[] sd = topDocs.scoreDocs;
diff --git a/lucene/sandbox/src/test/org/apache/lucene/search/TestTermAutomatonQuery.java b/lucene/sandbox/src/test/org/apache/lucene/search/TestTermAutomatonQuery.java
index 0d7ce58..3aaa3ed 100644
--- a/lucene/sandbox/src/test/org/apache/lucene/search/TestTermAutomatonQuery.java
+++ b/lucene/sandbox/src/test/org/apache/lucene/search/TestTermAutomatonQuery.java
@@ -606,6 +606,11 @@ public class TestTermAutomatonQuery extends LuceneTestCase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
+ @Override
public String toString(String field) {
return "RandomFilter(seed=" + seed + ",density=" + density + ")";
}
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/CompositeVerifyQuery.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/CompositeVerifyQuery.java
index cadacdc..e8149cb 100644
--- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/CompositeVerifyQuery.java
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/CompositeVerifyQuery.java
@@ -24,6 +24,7 @@ import org.apache.lucene.search.ConstantScoreScorer;
import org.apache.lucene.search.ConstantScoreWeight;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TwoPhaseIterator;
@@ -81,6 +82,11 @@ public class CompositeVerifyQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
final Weight indexQueryWeight = indexQuery.createWeight(searcher, ScoreMode.COMPLETE_NO_SCORES, boost);//scores aren't unsupported
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java
index 1bcb7b5..7fa9864 100644
--- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/composite/IntersectsRPTVerifyQuery.java
@@ -25,6 +25,7 @@ import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TwoPhaseIterator;
@@ -81,6 +82,11 @@ public class IntersectsRPTVerifyQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
return new ConstantScoreWeight(this, boost) {
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeQuery.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeQuery.java
index a5171c3..943aa31 100644
--- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeQuery.java
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/AbstractPrefixTreeQuery.java
@@ -29,6 +29,7 @@ import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
@@ -77,6 +78,13 @@ public abstract class AbstractPrefixTreeQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(fieldName)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
return new ConstantScoreWeight(this, boost) {
@Override
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java
index ff019c0..da70f0d 100644
--- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/serialized/SerializedDVStrategy.java
@@ -34,6 +34,7 @@ import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.DoubleValuesSource;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TwoPhaseIterator;
@@ -152,6 +153,11 @@ public class SerializedDVStrategy extends SpatialStrategy {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
+ @Override
public boolean equals(Object other) {
return sameClassAs(other) &&
predicateValueSource.equals(((PredicateValueSourceQuery) other).predicateValueSource);
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/PointVectorStrategy.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/PointVectorStrategy.java
index 9de43d1..6f2cb82 100644
--- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/PointVectorStrategy.java
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/vector/PointVectorStrategy.java
@@ -37,6 +37,7 @@ import org.apache.lucene.search.DoubleValues;
import org.apache.lucene.search.DoubleValuesSource;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TwoPhaseIterator;
@@ -266,6 +267,11 @@ public class PointVectorStrategy extends SpatialStrategy {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
Weight w = inner.createWeight(searcher, scoreMode, 1f);
return new ConstantScoreWeight(this, boost) {
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java
index 8fcf056..6b0f788 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/PointInGeo3DShapeQuery.java
@@ -25,6 +25,7 @@ import org.apache.lucene.search.ConstantScoreScorer;
import org.apache.lucene.search.ConstantScoreWeight;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
@@ -61,6 +62,13 @@ final class PointInGeo3DShapeQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ if (visitor.acceptField(field)) {
+ visitor.visitLeaf(this);
+ }
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
// I don't use RandomAccessWeight here: it's no good to approximate with "match all docs"; this is an inverted structure and should be
diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/CompletionWeight.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/CompletionWeight.java
index 1f97d55..8632c22 100644
--- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/CompletionWeight.java
+++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/CompletionWeight.java
@@ -17,11 +17,9 @@
package org.apache.lucene.search.suggest.document;
import java.io.IOException;
-import java.util.Set;
import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.index.Terms;
import org.apache.lucene.search.BulkScorer;
import org.apache.lucene.search.Explanation;
@@ -143,11 +141,6 @@ public class CompletionWeight extends Weight {
}
@Override
- public void extractTerms(Set<Term> terms) {
- // no-op
- }
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
//TODO
return null;
diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextQuery.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextQuery.java
index 1a2680c..bb2131d 100644
--- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextQuery.java
+++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextQuery.java
@@ -24,6 +24,7 @@ import java.util.TreeSet;
import org.apache.lucene.analysis.miscellaneous.ConcatenateGraphFilter;
import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Weight;
import org.apache.lucene.util.BytesRef;
@@ -336,4 +337,9 @@ public class ContextQuery extends CompletionQuery {
throw new UnsupportedOperationException();
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
}
diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/PrefixCompletionQuery.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/PrefixCompletionQuery.java
index a8da150..896d9c8 100644
--- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/PrefixCompletionQuery.java
+++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/PrefixCompletionQuery.java
@@ -21,6 +21,7 @@ import java.io.IOException;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Weight;
import org.apache.lucene.search.suggest.BitsProducer;
@@ -73,6 +74,10 @@ public class PrefixCompletionQuery extends CompletionQuery {
}
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
/**
* Gets the analyzer used to analyze the prefix.
*/
diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/RegexCompletionQuery.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/RegexCompletionQuery.java
index 6fa547a..4487f22 100644
--- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/RegexCompletionQuery.java
+++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/RegexCompletionQuery.java
@@ -20,6 +20,7 @@ import java.io.IOException;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Weight;
import org.apache.lucene.search.suggest.BitsProducer;
@@ -123,4 +124,9 @@ public class RegexCompletionQuery extends CompletionQuery {
public int hashCode() {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
}
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java
index b3d2f81..8989106 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingQuery.java
@@ -78,4 +78,9 @@ public final class AssertingQuery extends Query {
}
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ in.visit(visitor);
+ }
+
}
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/BlockScoreQueryWrapper.java b/lucene/test-framework/src/java/org/apache/lucene/search/BlockScoreQueryWrapper.java
index b15fa28..cfebc6a 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/BlockScoreQueryWrapper.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/BlockScoreQueryWrapper.java
@@ -19,11 +19,9 @@ package org.apache.lucene.search;
import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.util.ArrayUtil;
/**
@@ -73,6 +71,11 @@ public final class BlockScoreQueryWrapper extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ query.visit(visitor);
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
final Weight inWeight = query.createWeight(searcher, scoreMode, boost);
if (scoreMode.needsScores() == false) {
@@ -198,11 +201,6 @@ public final class BlockScoreQueryWrapper extends Query {
}
@Override
- public void extractTerms(Set<Term> terms) {
- inWeight.extractTerms(terms);
- }
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
return inWeight.explain(context, doc);
}
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/QueryUtils.java b/lucene/test-framework/src/java/org/apache/lucene/search/QueryUtils.java
index 840e78e..cdbac77 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/QueryUtils.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/QueryUtils.java
@@ -67,6 +67,9 @@ public class QueryUtils {
}
@Override
+ public void visit(QueryVisitor visitor) { }
+
+ @Override
public boolean equals(Object o) {
return o == this;
}
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/RandomApproximationQuery.java b/lucene/test-framework/src/java/org/apache/lucene/search/RandomApproximationQuery.java
index b43ccc4..445a39a 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/RandomApproximationQuery.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/RandomApproximationQuery.java
@@ -18,8 +18,8 @@ package org.apache.lucene.search;
import java.io.IOException;
import java.util.Random;
-import com.carrotsearch.randomizedtesting.generators.RandomNumbers;
+import com.carrotsearch.randomizedtesting.generators.RandomNumbers;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
@@ -46,6 +46,11 @@ public class RandomApproximationQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ query.visit(visitor);
+ }
+
+ @Override
public boolean equals(Object other) {
return sameClassAs(other) &&
query.equals(((RandomApproximationQuery) other).query);
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java b/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
index 1b81b77..27d4e6c 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
@@ -231,9 +231,8 @@ public abstract class ShardSearchingTestBase extends LuceneTestCase {
public Query rewrite(Query original) throws IOException {
final IndexSearcher localSearcher = new IndexSearcher(getIndexReader());
original = localSearcher.rewrite(original);
- final Weight weight = localSearcher.createWeight(original, ScoreMode.COMPLETE, 1);
final Set<Term> terms = new HashSet<>();
- weight.extractTerms(terms);
+ original.visit(QueryVisitor.termCollector(terms));
// Make a single request to remote nodes for term
// stats:
@@ -259,7 +258,7 @@ public abstract class ShardSearchingTestBase extends LuceneTestCase {
}
}
- return weight.getQuery();
+ return original;
}
@Override
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/spans/AssertingSpanQuery.java b/lucene/test-framework/src/java/org/apache/lucene/search/spans/AssertingSpanQuery.java
index f24a4ff..1040a3a 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/spans/AssertingSpanQuery.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/spans/AssertingSpanQuery.java
@@ -16,14 +16,15 @@
*/
package org.apache.lucene.search.spans;
+import java.io.IOException;
+import java.util.Objects;
+
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
-import java.io.IOException;
-import java.util.Objects;
-
/** Wraps a span query with asserts */
public class AssertingSpanQuery extends SpanQuery {
private final SpanQuery in;
@@ -61,6 +62,11 @@ public class AssertingSpanQuery extends SpanQuery {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ in.visit(visitor);
+ }
+
+ @Override
public Query clone() {
return new AssertingSpanQuery(in);
}
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/spans/AssertingSpanWeight.java b/lucene/test-framework/src/java/org/apache/lucene/search/spans/AssertingSpanWeight.java
index be04e00..9c73a43 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/spans/AssertingSpanWeight.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/spans/AssertingSpanWeight.java
@@ -18,7 +18,6 @@ package org.apache.lucene.search.spans;
import java.io.IOException;
import java.util.Map;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.Term;
@@ -61,12 +60,6 @@ public class AssertingSpanWeight extends SpanWeight {
public LeafSimScorer getSimScorer(LeafReaderContext context) throws IOException {
return in.getSimScorer(context);
}
-
- @Override
- public void extractTerms(Set<Term> terms) {
- in.extractTerms(terms);
- }
-
@Override
public SpanScorer scorer(LeafReaderContext context) throws IOException {
return in.scorer(context);
diff --git a/solr/contrib/ltr/src/java/org/apache/solr/ltr/LTRScoringQuery.java b/solr/contrib/ltr/src/java/org/apache/solr/ltr/LTRScoringQuery.java
index 332e1b2..811e940 100644
--- a/solr/contrib/ltr/src/java/org/apache/solr/ltr/LTRScoringQuery.java
+++ b/solr/contrib/ltr/src/java/org/apache/solr/ltr/LTRScoringQuery.java
@@ -24,7 +24,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
@@ -32,7 +31,6 @@ import java.util.concurrent.RunnableFuture;
import java.util.concurrent.Semaphore;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.DisiPriorityQueue;
import org.apache.lucene.search.DisiWrapper;
import org.apache.lucene.search.DisjunctionDISIApproximation;
@@ -40,6 +38,7 @@ import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
@@ -153,6 +152,11 @@ public class LTRScoringQuery extends Query {
return sameClassAs(o) && equalsTo(getClass().cast(o));
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
private boolean equalsTo(LTRScoringQuery other) {
if (ltrScoringModel == null) {
if (other.ltrScoringModel != null) {
@@ -443,13 +447,6 @@ public class LTRScoringQuery extends Query {
}
- @Override
- public void extractTerms(Set<Term> terms) {
- for (final Feature.FeatureWeight feature : extractedFeatureWeights) {
- feature.extractTerms(terms);
- }
- }
-
protected void reset() {
for (int i = 0; i < extractedFeatureWeights.length;++i){
int featId = extractedFeatureWeights[i].getIndex();
diff --git a/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/Feature.java b/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/Feature.java
index 066d281..c6e545b 100644
--- a/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/Feature.java
+++ b/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/Feature.java
@@ -19,14 +19,13 @@ package org.apache.solr.ltr.feature;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
import org.apache.solr.core.SolrResourceLoader;
@@ -134,6 +133,11 @@ public abstract class Feature extends Query {
return sameClassAs(o) && equalsTo(getClass().cast(o));
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
private boolean equalsTo(Feature other) {
if (index != other.index) {
return false;
@@ -261,11 +265,6 @@ public abstract class Feature extends Query {
return Feature.this.toString();
}
- @Override
- public void extractTerms(Set<Term> terms) {
- // no-op
- }
-
/**
* A 'recipe' for computing a feature
*/
diff --git a/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/OriginalScoreFeature.java b/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/OriginalScoreFeature.java
index 7a7770e..fc2fb90 100644
--- a/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/OriginalScoreFeature.java
+++ b/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/OriginalScoreFeature.java
@@ -19,10 +19,8 @@ package org.apache.solr.ltr.feature;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
@@ -80,11 +78,6 @@ public class OriginalScoreFeature extends Feature {
}
@Override
- public void extractTerms(Set<Term> terms) {
- w.extractTerms(terms);
- }
-
- @Override
public FeatureScorer scorer(LeafReaderContext context) throws IOException {
final Scorer originalScorer = w.scorer(context);
diff --git a/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/SolrFeature.java b/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/SolrFeature.java
index 7866ecc..d9851f5 100644
--- a/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/SolrFeature.java
+++ b/solr/contrib/ltr/src/java/org/apache/solr/ltr/feature/SolrFeature.java
@@ -21,10 +21,8 @@ import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
@@ -210,13 +208,6 @@ public class SolrFeature extends Feature {
}
@Override
- public void extractTerms(Set<Term> terms) {
- if (solrQueryWeight != null) {
- solrQueryWeight.extractTerms(terms);
- }
- }
-
- @Override
public FeatureScorer scorer(LeafReaderContext context) throws IOException {
Scorer solrScorer = null;
if (solrQueryWeight != null) {
diff --git a/solr/core/src/java/org/apache/solr/legacy/LegacyNumericRangeQuery.java b/solr/core/src/java/org/apache/solr/legacy/LegacyNumericRangeQuery.java
index d07e497..e39cfb7 100644
--- a/solr/core/src/java/org/apache/solr/legacy/LegacyNumericRangeQuery.java
+++ b/solr/core/src/java/org/apache/solr/legacy/LegacyNumericRangeQuery.java
@@ -27,16 +27,17 @@ import org.apache.lucene.document.IntPoint;
import org.apache.lucene.document.LongPoint;
import org.apache.lucene.index.FilteredTermsEnum;
import org.apache.lucene.index.PointValues;
+import org.apache.lucene.index.Term;
import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.util.AttributeSource;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.NumericUtils;
-import org.apache.lucene.index.Term; // for javadocs
/**
* <p>A {@link Query} that matches numeric values within a
@@ -533,5 +534,10 @@ public final class LegacyNumericRangeQuery<T extends Number> extends MultiTermQu
}
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
}
diff --git a/solr/core/src/java/org/apache/solr/parser/SolrQueryParserBase.java b/solr/core/src/java/org/apache/solr/parser/SolrQueryParserBase.java
index a97bae5..0019ed6 100644
--- a/solr/core/src/java/org/apache/solr/parser/SolrQueryParserBase.java
+++ b/solr/core/src/java/org/apache/solr/parser/SolrQueryParserBase.java
@@ -41,6 +41,7 @@ import org.apache.lucene.search.MultiPhraseQuery;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.RegexpQuery;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.util.QueryBuilder;
@@ -61,7 +62,7 @@ import org.apache.solr.search.QueryUtils;
import org.apache.solr.search.SolrConstantScoreQuery;
import org.apache.solr.search.SyntaxError;
-import static org.apache.solr.parser.SolrQueryParserBase.SynonymQueryStyle.*;
+import static org.apache.solr.parser.SolrQueryParserBase.SynonymQueryStyle.AS_SAME_TERM;
/** This class is overridden by QueryParser in QueryParser.jj
* and acts to separate the majority of the Java code from the .jj grammar file.
@@ -201,6 +202,11 @@ public abstract class SolrQueryParserBase extends QueryBuilder {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
+ @Override
public boolean equals(Object obj) {
return false;
}
diff --git a/solr/core/src/java/org/apache/solr/query/FilterQuery.java b/solr/core/src/java/org/apache/solr/query/FilterQuery.java
index 02cb88b..4df704e 100644
--- a/solr/core/src/java/org/apache/solr/query/FilterQuery.java
+++ b/solr/core/src/java/org/apache/solr/query/FilterQuery.java
@@ -24,6 +24,7 @@ import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Weight;
import org.apache.solr.search.DocSet;
@@ -67,6 +68,10 @@ public class FilterQuery extends ExtendedQueryBase {
return sb.toString();
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ q.visit(visitor);
+ }
@Override
public Query rewrite(IndexReader reader) throws IOException {
diff --git a/solr/core/src/java/org/apache/solr/query/SolrRangeQuery.java b/solr/core/src/java/org/apache/solr/query/SolrRangeQuery.java
index be58bbc..40a68e5 100644
--- a/solr/core/src/java/org/apache/solr/query/SolrRangeQuery.java
+++ b/solr/core/src/java/org/apache/solr/query/SolrRangeQuery.java
@@ -26,8 +26,8 @@ import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.PostingsEnum;
import org.apache.lucene.index.Term;
-import org.apache.lucene.index.TermStates;
import org.apache.lucene.index.TermState;
+import org.apache.lucene.index.TermStates;
import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.search.BooleanClause;
@@ -40,6 +40,7 @@ import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TermQuery;
@@ -126,6 +127,11 @@ public final class SolrRangeQuery extends ExtendedQueryBase implements DocSetPro
return buffer.toString();
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
private String endpoint(BytesRef ref) {
if (ref == null) return "*";
String toStr = Term.toString(ref);
diff --git a/solr/core/src/java/org/apache/solr/schema/LatLonType.java b/solr/core/src/java/org/apache/solr/schema/LatLonType.java
index 9f9dcd1..88ab20b 100644
--- a/solr/core/src/java/org/apache/solr/schema/LatLonType.java
+++ b/solr/core/src/java/org/apache/solr/schema/LatLonType.java
@@ -15,6 +15,7 @@
* limitations under the License.
*/
package org.apache.solr.schema;
+
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -34,6 +35,7 @@ import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.SortField;
@@ -593,6 +595,11 @@ class SpatialDistanceQuery extends ExtendedQueryBase implements PostFilter {
hash = hash * 31 + Double.doubleToLongBits(lonMin);
return (int) (hash >> 32 + hash);
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
}
diff --git a/solr/core/src/java/org/apache/solr/search/AbstractReRankQuery.java b/solr/core/src/java/org/apache/solr/search/AbstractReRankQuery.java
index 0c2fb82..c875658 100644
--- a/solr/core/src/java/org/apache/solr/search/AbstractReRankQuery.java
+++ b/solr/core/src/java/org/apache/solr/search/AbstractReRankQuery.java
@@ -23,6 +23,7 @@ import java.util.Set;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.Rescorer;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.TopDocsCollector;
@@ -83,4 +84,9 @@ public abstract class AbstractReRankQuery extends RankQuery {
final Weight mainWeight = mainQuery.createWeight(searcher, scoreMode, boost);
return new ReRankWeight(mainQuery, reRankQueryRescorer, searcher, mainWeight);
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
}
diff --git a/solr/core/src/java/org/apache/solr/search/AnalyticsQuery.java b/solr/core/src/java/org/apache/solr/search/AnalyticsQuery.java
index 1928c26..b32f518 100644
--- a/solr/core/src/java/org/apache/solr/search/AnalyticsQuery.java
+++ b/solr/core/src/java/org/apache/solr/search/AnalyticsQuery.java
@@ -17,8 +17,9 @@
package org.apache.solr.search;
import org.apache.lucene.search.IndexSearcher;
-import org.apache.solr.handler.component.ResponseBuilder;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.solr.handler.component.MergeStrategy;
+import org.apache.solr.handler.component.ResponseBuilder;
import org.apache.solr.request.SolrRequestInfo;
/**
@@ -77,4 +78,9 @@ public abstract class AnalyticsQuery extends ExtendedQueryBase implements PostFi
}
public abstract DelegatingCollector getAnalyticsCollector(ResponseBuilder rb, IndexSearcher searcher);
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
}
\ No newline at end of file
diff --git a/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java
index 53e5acd..44787ec 100644
--- a/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java
+++ b/solr/core/src/java/org/apache/solr/search/CollapsingQParserPlugin.java
@@ -54,6 +54,7 @@ import org.apache.lucene.search.FieldComparator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.LeafFieldComparator;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.Scorable;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Sort;
@@ -263,6 +264,11 @@ public class CollapsingQParserPlugin extends QParserPlugin {
nullPolicy == other.nullPolicy;
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
public int getCost() {
return Math.max(super.getCost(), 100);
}
diff --git a/solr/core/src/java/org/apache/solr/search/ExportQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/ExportQParserPlugin.java
index e3fbcac..bdf943e 100644
--- a/solr/core/src/java/org/apache/solr/search/ExportQParserPlugin.java
+++ b/solr/core/src/java/org/apache/solr/search/ExportQParserPlugin.java
@@ -25,6 +25,7 @@ import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.LeafCollector;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.Scorable;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.ScoreMode;
@@ -122,6 +123,11 @@ public class ExportQParserPlugin extends QParserPlugin {
return s;
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
public ExportQuery() {
}
diff --git a/solr/core/src/java/org/apache/solr/search/Filter.java b/solr/core/src/java/org/apache/solr/search/Filter.java
index 4a48bb6..bd70991 100644
--- a/solr/core/src/java/org/apache/solr/search/Filter.java
+++ b/solr/core/src/java/org/apache/solr/search/Filter.java
@@ -17,16 +17,15 @@
package org.apache.solr.search;
import java.io.IOException;
-import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.ConstantScoreScorer;
import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TwoPhaseIterator;
@@ -93,9 +92,6 @@ public abstract class Filter extends Query {
return new Weight(this) {
@Override
- public void extractTerms(Set<Term> terms) {}
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
final Scorer scorer = scorer(context);
final boolean match = (scorer != null && scorer.iterator().advance(doc) == doc);
@@ -142,4 +138,9 @@ public abstract class Filter extends Query {
}
};
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
}
diff --git a/solr/core/src/java/org/apache/solr/search/GraphTermsQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/GraphTermsQParserPlugin.java
index 0ce7f72..4ced113 100644
--- a/solr/core/src/java/org/apache/solr/search/GraphTermsQParserPlugin.java
+++ b/solr/core/src/java/org/apache/solr/search/GraphTermsQParserPlugin.java
@@ -22,7 +22,6 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import java.util.Set;
import org.apache.lucene.document.DoublePoint;
import org.apache.lucene.document.FloatPoint;
@@ -51,6 +50,7 @@ import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
@@ -239,6 +239,11 @@ public class GraphTermsQParserPlugin extends QParserPlugin {
return builder.toString();
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
private class WeightOrDocIdSet {
final Weight weight;
final DocIdSet set;
@@ -267,14 +272,6 @@ public class GraphTermsQParserPlugin extends QParserPlugin {
return new ConstantScoreWeight(this, boost) {
- @Override
- public void extractTerms(Set<Term> terms) {
- // no-op
- // This query is for abuse cases when the number of terms is too high to
- // run efficiently as a BooleanQuery. So likewise we hide its terms in
- // order to protect highlighters
- }
-
private WeightOrDocIdSet rewrite(LeafReaderContext context) throws IOException {
final LeafReader reader = context.reader();
Terms terms = reader.terms(field);
@@ -781,5 +778,10 @@ abstract class PointSetQuery extends Query implements DocSetProducer {
return sb.toString();
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
protected abstract String toString(byte[] value);
}
diff --git a/solr/core/src/java/org/apache/solr/search/HashQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/HashQParserPlugin.java
index 2af5bd8..2cdf9f3 100644
--- a/solr/core/src/java/org/apache/solr/search/HashQParserPlugin.java
+++ b/solr/core/src/java/org/apache/solr/search/HashQParserPlugin.java
@@ -31,6 +31,7 @@ import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.LeafCollector;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.Scorable;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Weight;
@@ -113,6 +114,11 @@ public class HashQParserPlugin extends QParserPlugin {
worker == other.worker;
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
public HashQuery(String[] keys, int workers, int worker) {
this.keys = keys;
this.workers = workers;
diff --git a/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java
index 4e832a0..c6fb0de 100644
--- a/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java
+++ b/solr/core/src/java/org/apache/solr/search/JoinQParserPlugin.java
@@ -36,6 +36,7 @@ import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
@@ -165,6 +166,11 @@ class JoinQuery extends Query {
}
@Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
+ @Override
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
return new JoinQueryWeight((SolrIndexSearcher) searcher, scoreMode, boost);
}
diff --git a/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java b/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java
index b032dc0..0d37abb 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrConstantScoreQuery.java
@@ -28,6 +28,7 @@ import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
@@ -138,4 +139,9 @@ public class SolrConstantScoreQuery extends Query implements ExtendedQuery {
return 31 * classHash() + filter.hashCode();
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
}
diff --git a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
index ab0996d..210e0ad 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
@@ -2310,6 +2310,11 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
return "SolrFilter";
}
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
private class FilterSet extends DocIdSet {
private final DocIdSet docIdSet;
private final LeafReaderContext context;
diff --git a/solr/core/src/java/org/apache/solr/search/WrappedQuery.java b/solr/core/src/java/org/apache/solr/search/WrappedQuery.java
index bea01a6..e123c50 100644
--- a/solr/core/src/java/org/apache/solr/search/WrappedQuery.java
+++ b/solr/core/src/java/org/apache/solr/search/WrappedQuery.java
@@ -16,14 +16,15 @@
*/
package org.apache.solr.search;
+import java.io.IOException;
+
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Weight;
-import java.io.IOException;
-
/** A simple query that wraps another query and implements ExtendedQuery. */
public final class WrappedQuery extends ExtendedQueryBase {
private Query q;
@@ -52,6 +53,11 @@ public final class WrappedQuery extends ExtendedQueryBase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+ q.visit(visitor);
+ }
+
+ @Override
public int hashCode() {
return q.hashCode();
}
diff --git a/solr/core/src/java/org/apache/solr/search/join/BlockJoinFacetFilter.java b/solr/core/src/java/org/apache/solr/search/join/BlockJoinFacetFilter.java
index 83e9a8f..5d65422 100644
--- a/solr/core/src/java/org/apache/solr/search/join/BlockJoinFacetFilter.java
+++ b/solr/core/src/java/org/apache/solr/search/join/BlockJoinFacetFilter.java
@@ -20,6 +20,7 @@ import java.util.Objects;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.solr.search.DelegatingCollector;
import org.apache.solr.search.PostFilter;
@@ -87,4 +88,9 @@ class BlockJoinFacetFilter extends Query implements PostFilter {
public int hashCode() {
return classHash() * 31 + blockJoinFacetCollector.hashCode();
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
}
diff --git a/solr/core/src/java/org/apache/solr/search/join/GraphQuery.java b/solr/core/src/java/org/apache/solr/search/join/GraphQuery.java
index 4402a26..accb1dc 100644
--- a/solr/core/src/java/org/apache/solr/search/join/GraphQuery.java
+++ b/solr/core/src/java/org/apache/solr/search/join/GraphQuery.java
@@ -20,7 +20,6 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
-import java.util.Set;
import java.util.TreeSet;
import org.apache.lucene.index.LeafReaderContext;
@@ -34,6 +33,7 @@ import org.apache.lucene.search.DocValuesFieldExistsQuery;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
@@ -281,11 +281,6 @@ public class GraphQuery extends Query {
public boolean isCacheable(LeafReaderContext ctx) {
return true;
}
-
- @Override
- public void extractTerms(Set<Term> terms) {
- // NoOp for now , not used.. / supported
- }
}
@@ -441,5 +436,10 @@ public class GraphQuery extends Query {
Objects.equals(toField, other.toField) &&
Objects.equals(traversalFilter, other.traversalFilter);
}
-
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
+
}
diff --git a/solr/core/src/java/org/apache/solr/search/join/ScoreJoinQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/join/ScoreJoinQParserPlugin.java
index 55d58fc..c2f8662 100644
--- a/solr/core/src/java/org/apache/solr/search/join/ScoreJoinQParserPlugin.java
+++ b/solr/core/src/java/org/apache/solr/search/join/ScoreJoinQParserPlugin.java
@@ -23,6 +23,7 @@ import java.util.Objects;
import org.apache.lucene.index.DocValuesType;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.Weight;
import org.apache.lucene.search.join.JoinUtil;
import org.apache.lucene.search.join.ScoreMode;
@@ -195,6 +196,11 @@ public class ScoreJoinQParserPlugin extends QParserPlugin {
Objects.equals(scoreMode, other.scoreMode) &&
Objects.equals(toField, other.toField);
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
}
diff --git a/solr/core/src/java/org/apache/solr/search/stats/ExactStatsCache.java b/solr/core/src/java/org/apache/solr/search/stats/ExactStatsCache.java
index 290b7c1..fe315d2 100644
--- a/solr/core/src/java/org/apache/solr/search/stats/ExactStatsCache.java
+++ b/solr/core/src/java/org/apache/solr/search/stats/ExactStatsCache.java
@@ -27,10 +27,10 @@ import java.util.Map.Entry;
import java.util.Set;
import com.google.common.collect.Lists;
-import org.apache.lucene.index.IndexReaderContext;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermStates;
import org.apache.lucene.search.CollectionStatistics;
+import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.TermStatistics;
@@ -157,26 +157,32 @@ public class ExactStatsCache extends StatsCache {
Query q = rb.getQuery();
try {
HashSet<Term> terms = new HashSet<>();
- searcher.createWeight(searcher.rewrite(q), ScoreMode.COMPLETE, 1).extractTerms(terms);
- IndexReaderContext context = searcher.getTopReaderContext();
HashMap<String,TermStats> statsMap = new HashMap<>();
HashMap<String,CollectionStats> colMap = new HashMap<>();
- for (Term t : terms) {
- TermStates termStates = TermStates.build(context, t, true);
-
- if (!colMap.containsKey(t.field())) { // collection stats for this field
- CollectionStatistics collectionStatistics = searcher.localCollectionStatistics(t.field());
- if (collectionStatistics != null) {
- colMap.put(t.field(), new CollectionStats(collectionStatistics));
+ IndexSearcher statsCollectingSearcher = new IndexSearcher(searcher.getIndexReader()){
+ @Override
+ public CollectionStatistics collectionStatistics(String field) throws IOException {
+ CollectionStatistics cs = super.collectionStatistics(field);
+ if (cs != null) {
+ colMap.put(field, new CollectionStats(cs));
}
+ return cs;
}
- TermStatistics tst = searcher.localTermStatistics(t, termStates);
- if (tst == null) { // skip terms that are not present here
- continue;
+ @Override
+ public TermStatistics termStatistics(Term term, TermStates context) throws IOException {
+ TermStatistics ts = super.termStatistics(term, context);
+ if (ts == null) {
+ return null;
+ }
+ terms.add(term);
+ statsMap.put(term.toString(), new TermStats(term.field(), ts));
+ return ts;
}
+ };
+ statsCollectingSearcher.createWeight(searcher.rewrite(q), ScoreMode.COMPLETE, 1);
- statsMap.put(t.toString(), new TermStats(t.field(), tst));
+ for (Term t : terms) {
rb.rsp.add(TERMS_KEY, t.toString());
}
if (statsMap.size() != 0) { //Don't add empty keys
diff --git a/solr/core/src/java/org/apache/solr/update/DeleteByQueryWrapper.java b/solr/core/src/java/org/apache/solr/update/DeleteByQueryWrapper.java
index 9a16f60..08c1540 100644
--- a/solr/core/src/java/org/apache/solr/update/DeleteByQueryWrapper.java
+++ b/solr/core/src/java/org/apache/solr/update/DeleteByQueryWrapper.java
@@ -18,15 +18,14 @@ package org.apache.solr.update;
import java.io.IOException;
import java.util.Objects;
-import java.util.Set;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.Term;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
@@ -73,11 +72,6 @@ final class DeleteByQueryWrapper extends Query {
final Weight inner = in.createWeight(privateContext, scoreMode, boost);
return new Weight(DeleteByQueryWrapper.this) {
@Override
- public void extractTerms(Set<Term> terms) {
- throw new UnsupportedOperationException();
- }
-
- @Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException { throw new UnsupportedOperationException(); }
@Override
@@ -116,4 +110,9 @@ final class DeleteByQueryWrapper extends Query {
return Objects.equals(in, other.in) &&
Objects.equals(schema, other.schema);
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
}
diff --git a/solr/core/src/java/org/apache/solr/update/SolrIndexSplitter.java b/solr/core/src/java/org/apache/solr/update/SolrIndexSplitter.java
index 0360afc..b56bcb6 100644
--- a/solr/core/src/java/org/apache/solr/update/SolrIndexSplitter.java
+++ b/solr/core/src/java/org/apache/solr/update/SolrIndexSplitter.java
@@ -45,6 +45,7 @@ import org.apache.lucene.search.ConstantScoreWeight;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
@@ -529,6 +530,11 @@ public class SolrIndexSplitter {
public int hashCode() {
return partition;
}
+
+ @Override
+ public void visit(QueryVisitor visitor) {
+ visitor.visitLeaf(this);
+ }
}
static FixedBitSet[] split(LeafReaderContext readerContext, int numPieces, SchemaField field, DocRouter.Range[] rangesArr,
diff --git a/solr/core/src/test/org/apache/solr/search/RankQueryTestPlugin.java b/solr/core/src/test/org/apache/solr/search/RankQueryTestPlugin.java
index bc38397..1024883 100644
--- a/solr/core/src/test/org/apache/solr/search/RankQueryTestPlugin.java
+++ b/solr/core/src/test/org/apache/solr/search/RankQueryTestPlugin.java
@@ -36,6 +36,7 @@ import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.LeafCollector;
import org.apache.lucene.search.LeafFieldComparator;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.Scorable;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.ScoreMode;
@@ -112,6 +113,11 @@ public class RankQueryTestPlugin extends QParserPlugin {
}
@Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
+ @Override
public String toString(String field) {
return q.toString(field);
}
diff --git a/solr/core/src/test/org/apache/solr/uninverting/TestFieldCacheSortRandom.java b/solr/core/src/test/org/apache/solr/uninverting/TestFieldCacheSortRandom.java
index bca4794..9152632 100644
--- a/solr/core/src/test/org/apache/solr/uninverting/TestFieldCacheSortRandom.java
+++ b/solr/core/src/test/org/apache/solr/uninverting/TestFieldCacheSortRandom.java
@@ -44,6 +44,7 @@ import org.apache.lucene.search.ConstantScoreWeight;
import org.apache.lucene.search.FieldDoc;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryVisitor;
import org.apache.lucene.search.ScoreMode;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Sort;
@@ -54,8 +55,8 @@ import org.apache.lucene.store.Directory;
import org.apache.lucene.util.BitSetIterator;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.FixedBitSet;
-import org.apache.solr.SolrTestCase;
import org.apache.lucene.util.TestUtil;
+import org.apache.solr.SolrTestCase;
import org.apache.solr.uninverting.UninvertingReader.Type;
/** random sorting tests with uninversion */
@@ -298,6 +299,11 @@ public class TestFieldCacheSortRandom extends SolrTestCase {
}
@Override
+ public void visit(QueryVisitor visitor) {
+
+ }
+
+ @Override
public String toString(String field) {
return "RandomFilter(density=" + density + ")";
}