mirror of https://github.com/apache/lucene.git
Implement ScorerSupplier for Sorted(Set)DocValuesField#newSlowRangeQuery (#12132)
Similar to use of ScorerSupplier in #12129, implement it here too, because creation of a Scorer requires lookupTerm() operations in the DV terms dictionary. This results in wasted effort/random accesses, if, based on the cost(), IndexOrDocValuesQuery decides not to use this query.
This commit is contained in:
parent
8340b01c3c
commit
3ad2ede395
|
@ -24,12 +24,14 @@ import org.apache.lucene.index.SortedDocValues;
|
||||||
import org.apache.lucene.index.SortedSetDocValues;
|
import org.apache.lucene.index.SortedSetDocValues;
|
||||||
import org.apache.lucene.search.ConstantScoreScorer;
|
import org.apache.lucene.search.ConstantScoreScorer;
|
||||||
import org.apache.lucene.search.ConstantScoreWeight;
|
import org.apache.lucene.search.ConstantScoreWeight;
|
||||||
|
import org.apache.lucene.search.DocIdSetIterator;
|
||||||
import org.apache.lucene.search.FieldExistsQuery;
|
import org.apache.lucene.search.FieldExistsQuery;
|
||||||
import org.apache.lucene.search.IndexSearcher;
|
import org.apache.lucene.search.IndexSearcher;
|
||||||
import org.apache.lucene.search.Query;
|
import org.apache.lucene.search.Query;
|
||||||
import org.apache.lucene.search.QueryVisitor;
|
import org.apache.lucene.search.QueryVisitor;
|
||||||
import org.apache.lucene.search.ScoreMode;
|
import org.apache.lucene.search.ScoreMode;
|
||||||
import org.apache.lucene.search.Scorer;
|
import org.apache.lucene.search.Scorer;
|
||||||
|
import org.apache.lucene.search.ScorerSupplier;
|
||||||
import org.apache.lucene.search.TwoPhaseIterator;
|
import org.apache.lucene.search.TwoPhaseIterator;
|
||||||
import org.apache.lucene.search.Weight;
|
import org.apache.lucene.search.Weight;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
|
@ -106,13 +108,29 @@ final class SortedSetDocValuesRangeQuery extends Query {
|
||||||
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost)
|
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
return new ConstantScoreWeight(this, boost) {
|
return new ConstantScoreWeight(this, boost) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Scorer scorer(LeafReaderContext context) throws IOException {
|
public Scorer scorer(LeafReaderContext context) throws IOException {
|
||||||
|
ScorerSupplier scorerSupplier = scorerSupplier(context);
|
||||||
|
if (scorerSupplier == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return scorerSupplier.get(Long.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScorerSupplier scorerSupplier(LeafReaderContext context) throws IOException {
|
||||||
|
final Weight weight = this;
|
||||||
if (context.reader().getFieldInfos().fieldInfo(field) == null) {
|
if (context.reader().getFieldInfos().fieldInfo(field) == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
SortedSetDocValues values = DocValues.getSortedSet(context.reader(), field);
|
SortedSetDocValues values = DocValues.getSortedSet(context.reader(), field);
|
||||||
|
|
||||||
|
// implement ScorerSupplier, since we do some expensive stuff to make a scorer
|
||||||
|
return new ScorerSupplier() {
|
||||||
|
@Override
|
||||||
|
public Scorer get(long leadCost) throws IOException {
|
||||||
|
|
||||||
final long minOrd;
|
final long minOrd;
|
||||||
if (lowerValue == null) {
|
if (lowerValue == null) {
|
||||||
minOrd = 0;
|
minOrd = 0;
|
||||||
|
@ -141,8 +159,9 @@ final class SortedSetDocValuesRangeQuery extends Query {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// no terms matched in this segment
|
||||||
if (minOrd > maxOrd) {
|
if (minOrd > maxOrd) {
|
||||||
return null;
|
return new ConstantScoreScorer(weight, score(), scoreMode, DocIdSetIterator.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
final SortedDocValues singleton = DocValues.unwrapSingleton(values);
|
final SortedDocValues singleton = DocValues.unwrapSingleton(values);
|
||||||
|
@ -171,7 +190,8 @@ final class SortedSetDocValuesRangeQuery extends Query {
|
||||||
if (ord < minOrd) {
|
if (ord < minOrd) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Values are sorted, so the first ord that is >= minOrd is our best candidate
|
// Values are sorted, so the first ord that is >= minOrd is our best
|
||||||
|
// candidate
|
||||||
return ord <= maxOrd;
|
return ord <= maxOrd;
|
||||||
}
|
}
|
||||||
return false; // all ords were < minOrd
|
return false; // all ords were < minOrd
|
||||||
|
@ -183,7 +203,14 @@ final class SortedSetDocValuesRangeQuery extends Query {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return new ConstantScoreScorer(this, score(), scoreMode, iterator);
|
return new ConstantScoreScorer(weight, score(), scoreMode, iterator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long cost() {
|
||||||
|
return values.cost();
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue