mirror of https://github.com/apache/lucene.git
LUCENE-8464: ConstantScoreScorer now implements setMinCompetitveScore in order to early terminate the iterator if the minimum score is greater than the constant score.
Signed-off-by: Jim Ferenczi <jimczi@apache.org>
This commit is contained in:
parent
5aa6782d87
commit
b4449c73e4
|
@ -192,6 +192,10 @@ Optimizations
|
||||||
* LUCENE-8507: TopFieldCollector can now update the minimum competitive score if the primary sort
|
* LUCENE-8507: TopFieldCollector can now update the minimum competitive score if the primary sort
|
||||||
is by relevancy and the total hit count is not required. (Jim Ferenczi)
|
is by relevancy and the total hit count is not required. (Jim Ferenczi)
|
||||||
|
|
||||||
|
* LUCENE-8464: ConstantScoreScorer now implements setMinCompetitveScore in order
|
||||||
|
to early terminate the iterator if the minimum score is greater than the constant
|
||||||
|
score. (Christophe Bismuth via Jim Ferenczi)
|
||||||
|
|
||||||
======================= Lucene 7.7.0 =======================
|
======================= Lucene 7.7.0 =======================
|
||||||
|
|
||||||
Build
|
Build
|
||||||
|
|
|
@ -139,7 +139,7 @@ final class LatLonDocValuesBoxQuery extends Query {
|
||||||
return 5; // 5 comparisons
|
return 5; // 5 comparisons
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return new ConstantScoreScorer(this, boost, iterator);
|
return new ConstantScoreScorer(this, boost, scoreMode, iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -126,7 +126,7 @@ final class LatLonDocValuesDistanceQuery extends Query {
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
return new ConstantScoreScorer(this, boost, iterator);
|
return new ConstantScoreScorer(this, boost, scoreMode, iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -160,10 +160,10 @@ final class LatLonPointDistanceQuery extends Query {
|
||||||
int[] cost = new int[]{reader.maxDoc()};
|
int[] cost = new int[]{reader.maxDoc()};
|
||||||
values.intersect(getInverseIntersectVisitor(result, cost));
|
values.intersect(getInverseIntersectVisitor(result, cost));
|
||||||
final DocIdSetIterator iterator = new BitSetIterator(result, cost[0]);
|
final DocIdSetIterator iterator = new BitSetIterator(result, cost[0]);
|
||||||
return new ConstantScoreScorer(weight, score(), iterator);
|
return new ConstantScoreScorer(weight, score(), scoreMode, iterator);
|
||||||
}
|
}
|
||||||
values.intersect(visitor);
|
values.intersect(visitor);
|
||||||
return new ConstantScoreScorer(weight, score(), result.build().iterator());
|
return new ConstantScoreScorer(weight, score(), scoreMode, result.build().iterator());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -158,7 +158,7 @@ final class LatLonPointInPolygonQuery extends Query {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return new ConstantScoreScorer(this, score(), result.build().iterator());
|
return new ConstantScoreScorer(this, score(), scoreMode, result.build().iterator());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -314,7 +314,7 @@ abstract class RangeFieldQuery extends Query {
|
||||||
return new ScorerSupplier() {
|
return new ScorerSupplier() {
|
||||||
@Override
|
@Override
|
||||||
public Scorer get(long leadCost) {
|
public Scorer get(long leadCost) {
|
||||||
return new ConstantScoreScorer(weight, score(), DocIdSetIterator.all(reader.maxDoc()));
|
return new ConstantScoreScorer(weight, score(), scoreMode, DocIdSetIterator.all(reader.maxDoc()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -333,7 +333,7 @@ abstract class RangeFieldQuery extends Query {
|
||||||
public Scorer get(long leadCost) throws IOException {
|
public Scorer get(long leadCost) throws IOException {
|
||||||
values.intersect(visitor);
|
values.intersect(visitor);
|
||||||
DocIdSetIterator iterator = result.build().iterator();
|
DocIdSetIterator iterator = result.build().iterator();
|
||||||
return new ConstantScoreScorer(weight, score(), iterator);
|
return new ConstantScoreScorer(weight, score(), scoreMode, iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -143,7 +143,7 @@ abstract class SortedNumericDocValuesRangeQuery extends Query {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return new ConstantScoreScorer(this, score(), iterator);
|
return new ConstantScoreScorer(this, score(), scoreMode, iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -180,7 +180,7 @@ abstract class SortedSetDocValuesRangeQuery extends Query {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return new ConstantScoreScorer(this, score(), iterator);
|
return new ConstantScoreScorer(this, score(), scoreMode, iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -25,7 +25,38 @@ import java.io.IOException;
|
||||||
*/
|
*/
|
||||||
public final class ConstantScoreScorer extends Scorer {
|
public final class ConstantScoreScorer extends Scorer {
|
||||||
|
|
||||||
|
private class DocIdSetIteratorWrapper extends DocIdSetIterator {
|
||||||
|
int doc = -1;
|
||||||
|
DocIdSetIterator delegate;
|
||||||
|
|
||||||
|
DocIdSetIteratorWrapper(DocIdSetIterator delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int docID() {
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int nextDoc() throws IOException {
|
||||||
|
return doc = delegate.nextDoc();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int advance(int target) throws IOException {
|
||||||
|
return doc = delegate.advance(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long cost() {
|
||||||
|
return delegate.cost();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final float score;
|
private final float score;
|
||||||
|
private final ScoreMode scoreMode;
|
||||||
|
private final DocIdSetIterator approximation;
|
||||||
private final TwoPhaseIterator twoPhaseIterator;
|
private final TwoPhaseIterator twoPhaseIterator;
|
||||||
private final DocIdSetIterator disi;
|
private final DocIdSetIterator disi;
|
||||||
|
|
||||||
|
@ -33,24 +64,45 @@ public final class ConstantScoreScorer extends Scorer {
|
||||||
* drive iteration. Two phase iteration will not be supported.
|
* drive iteration. Two phase iteration will not be supported.
|
||||||
* @param weight the parent weight
|
* @param weight the parent weight
|
||||||
* @param score the score to return on each document
|
* @param score the score to return on each document
|
||||||
|
* @param scoreMode the score mode
|
||||||
* @param disi the iterator that defines matching documents */
|
* @param disi the iterator that defines matching documents */
|
||||||
public ConstantScoreScorer(Weight weight, float score, DocIdSetIterator disi) {
|
public ConstantScoreScorer(Weight weight, float score, ScoreMode scoreMode, DocIdSetIterator disi) {
|
||||||
super(weight);
|
super(weight);
|
||||||
this.score = score;
|
this.score = score;
|
||||||
|
this.scoreMode = scoreMode;
|
||||||
|
this.approximation = scoreMode == ScoreMode.TOP_SCORES ? new DocIdSetIteratorWrapper(disi) : disi;
|
||||||
this.twoPhaseIterator = null;
|
this.twoPhaseIterator = null;
|
||||||
this.disi = disi;
|
this.disi = this.approximation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Constructor based on a {@link TwoPhaseIterator}. In that case the
|
/** Constructor based on a {@link TwoPhaseIterator}. In that case the
|
||||||
* {@link Scorer} will support two-phase iteration.
|
* {@link Scorer} will support two-phase iteration.
|
||||||
* @param weight the parent weight
|
* @param weight the parent weight
|
||||||
* @param score the score to return on each document
|
* @param score the score to return on each document
|
||||||
|
* @param scoreMode the score mode
|
||||||
* @param twoPhaseIterator the iterator that defines matching documents */
|
* @param twoPhaseIterator the iterator that defines matching documents */
|
||||||
public ConstantScoreScorer(Weight weight, float score, TwoPhaseIterator twoPhaseIterator) {
|
public ConstantScoreScorer(Weight weight, float score, ScoreMode scoreMode, TwoPhaseIterator twoPhaseIterator) {
|
||||||
super(weight);
|
super(weight);
|
||||||
this.score = score;
|
this.score = score;
|
||||||
this.twoPhaseIterator = twoPhaseIterator;
|
this.scoreMode = scoreMode;
|
||||||
this.disi = TwoPhaseIterator.asDocIdSetIterator(twoPhaseIterator);
|
if (scoreMode == ScoreMode.TOP_SCORES) {
|
||||||
|
this.approximation = new DocIdSetIteratorWrapper(twoPhaseIterator.approximation());
|
||||||
|
this.twoPhaseIterator = new TwoPhaseIterator(this.approximation) {
|
||||||
|
@Override
|
||||||
|
public boolean matches() throws IOException {
|
||||||
|
return twoPhaseIterator.matches();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float matchCost() {
|
||||||
|
return twoPhaseIterator.matchCost();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
this.approximation = twoPhaseIterator.approximation();
|
||||||
|
this.twoPhaseIterator = twoPhaseIterator;
|
||||||
|
}
|
||||||
|
this.disi = TwoPhaseIterator.asDocIdSetIterator(this.twoPhaseIterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -58,6 +110,13 @@ public final class ConstantScoreScorer extends Scorer {
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMinCompetitiveScore(float minScore) throws IOException {
|
||||||
|
if (scoreMode == ScoreMode.TOP_SCORES && minScore > score) {
|
||||||
|
((DocIdSetIteratorWrapper) approximation).delegate = DocIdSetIterator.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DocIdSetIterator iterator() {
|
public DocIdSetIterator iterator() {
|
||||||
return disi;
|
return disi;
|
||||||
|
@ -79,4 +138,3 @@ public final class ConstantScoreScorer extends Scorer {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ public final class DocValuesFieldExistsQuery extends Query {
|
||||||
if (iterator == null) {
|
if (iterator == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new ConstantScoreScorer(this, score(), iterator);
|
return new ConstantScoreScorer(this, score(), scoreMode, iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -150,7 +150,7 @@ public final class DocValuesRewriteMethod extends MultiTermQuery.RewriteMethod {
|
||||||
}
|
}
|
||||||
} while (termsEnum.next() != null);
|
} while (termsEnum.next() != null);
|
||||||
|
|
||||||
return new ConstantScoreScorer(this, score(), new TwoPhaseIterator(fcsi) {
|
return new ConstantScoreScorer(this, score(), scoreMode, new TwoPhaseIterator(fcsi) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches() throws IOException {
|
public boolean matches() throws IOException {
|
||||||
|
|
|
@ -766,7 +766,7 @@ public class LRUQueryCache implements QueryCache, Accountable {
|
||||||
return new ScorerSupplier() {
|
return new ScorerSupplier() {
|
||||||
@Override
|
@Override
|
||||||
public Scorer get(long LeadCost) throws IOException {
|
public Scorer get(long LeadCost) throws IOException {
|
||||||
return new ConstantScoreScorer(CachingWrapperWeight.this, 0f, disi);
|
return new ConstantScoreScorer(CachingWrapperWeight.this, 0f, ScoreMode.COMPLETE_NO_SCORES, disi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -844,7 +844,7 @@ public class LRUQueryCache implements QueryCache, Accountable {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DefaultBulkScorer(new ConstantScoreScorer(this, 0f, disi));
|
return new DefaultBulkScorer(new ConstantScoreScorer(this, 0f, ScoreMode.COMPLETE_NO_SCORES, disi));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ public final class MatchAllDocsQuery extends Query {
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public Scorer scorer(LeafReaderContext context) throws IOException {
|
public Scorer scorer(LeafReaderContext context) throws IOException {
|
||||||
return new ConstantScoreScorer(this, score(), DocIdSetIterator.all(context.reader().maxDoc()));
|
return new ConstantScoreScorer(this, score(), scoreMode, DocIdSetIterator.all(context.reader().maxDoc()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -185,7 +185,7 @@ final class MultiTermQueryConstantScoreWrapper<Q extends MultiTermQuery> extends
|
||||||
if (disi == null) {
|
if (disi == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new ConstantScoreScorer(this, score(), disi);
|
return new ConstantScoreScorer(this, score(), scoreMode, disi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -73,7 +73,7 @@ public final class NormsFieldExistsQuery extends Query {
|
||||||
}
|
}
|
||||||
LeafReader reader = context.reader();
|
LeafReader reader = context.reader();
|
||||||
DocIdSetIterator iterator = reader.getNormValues(field);
|
DocIdSetIterator iterator = reader.getNormValues(field);
|
||||||
return new ConstantScoreScorer(this, score(), iterator);
|
return new ConstantScoreScorer(this, score(), scoreMode, iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -149,7 +149,7 @@ public abstract class PointInSetQuery extends Query {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ConstantScoreScorer(this, score(), result.build().iterator());
|
return new ConstantScoreScorer(this, score(), scoreMode, result.build().iterator());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -264,8 +264,7 @@ public abstract class PointRangeQuery extends Query {
|
||||||
return new ScorerSupplier() {
|
return new ScorerSupplier() {
|
||||||
@Override
|
@Override
|
||||||
public Scorer get(long leadCost) {
|
public Scorer get(long leadCost) {
|
||||||
return new ConstantScoreScorer(weight, score(),
|
return new ConstantScoreScorer(weight, score(), scoreMode, DocIdSetIterator.all(reader.maxDoc()));
|
||||||
DocIdSetIterator.all(reader.maxDoc()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -293,12 +292,12 @@ public abstract class PointRangeQuery extends Query {
|
||||||
int[] cost = new int[] { reader.maxDoc() };
|
int[] cost = new int[] { reader.maxDoc() };
|
||||||
values.intersect(getInverseIntersectVisitor(result, cost));
|
values.intersect(getInverseIntersectVisitor(result, cost));
|
||||||
final DocIdSetIterator iterator = new BitSetIterator(result, cost[0]);
|
final DocIdSetIterator iterator = new BitSetIterator(result, cost[0]);
|
||||||
return new ConstantScoreScorer(weight, score(), iterator);
|
return new ConstantScoreScorer(weight, score(), scoreMode, iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
values.intersect(visitor);
|
values.intersect(visitor);
|
||||||
DocIdSetIterator iterator = result.build().iterator();
|
DocIdSetIterator iterator = result.build().iterator();
|
||||||
return new ConstantScoreScorer(weight, score(), iterator);
|
return new ConstantScoreScorer(weight, score(), scoreMode, iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -298,7 +298,7 @@ public class TermInSetQuery extends Query implements Accountable {
|
||||||
if (disi == null) {
|
if (disi == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new ConstantScoreScorer(this, score(), disi);
|
return new ConstantScoreScorer(this, score(), scoreMode, disi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -234,12 +234,12 @@ public class TestConjunctionDISI extends LuceneTestCase {
|
||||||
case 0:
|
case 0:
|
||||||
// simple iterator
|
// simple iterator
|
||||||
sets[i] = set;
|
sets[i] = set;
|
||||||
iterators[i] = new ConstantScoreScorer(new FakeWeight(), 0f, anonymizeIterator(new BitDocIdSet(set).iterator()));
|
iterators[i] = new ConstantScoreScorer(new FakeWeight(), 0f, ScoreMode.TOP_SCORES, anonymizeIterator(new BitDocIdSet(set).iterator()));
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// bitSet iterator
|
// bitSet iterator
|
||||||
sets[i] = set;
|
sets[i] = set;
|
||||||
iterators[i] = new ConstantScoreScorer(new FakeWeight(), 0f, new BitDocIdSet(set).iterator());
|
iterators[i] = new ConstantScoreScorer(new FakeWeight(), 0f, ScoreMode.TOP_SCORES, new BitDocIdSet(set).iterator());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// scorer with approximation
|
// scorer with approximation
|
||||||
|
@ -270,7 +270,7 @@ public class TestConjunctionDISI extends LuceneTestCase {
|
||||||
if (random().nextBoolean()) {
|
if (random().nextBoolean()) {
|
||||||
// simple iterator
|
// simple iterator
|
||||||
sets[i] = set;
|
sets[i] = set;
|
||||||
iterators[i] = new ConstantScoreScorer(new FakeWeight(), 0f, new BitDocIdSet(set).iterator());
|
iterators[i] = new ConstantScoreScorer(new FakeWeight(), 0f, ScoreMode.COMPLETE_NO_SCORES, new BitDocIdSet(set).iterator());
|
||||||
} else {
|
} else {
|
||||||
// scorer with approximation
|
// scorer with approximation
|
||||||
final FixedBitSet confirmed = clearRandomBits(set);
|
final FixedBitSet confirmed = clearRandomBits(set);
|
||||||
|
@ -306,12 +306,12 @@ public class TestConjunctionDISI extends LuceneTestCase {
|
||||||
case 0:
|
case 0:
|
||||||
// simple iterator
|
// simple iterator
|
||||||
sets[i] = set;
|
sets[i] = set;
|
||||||
newIterator = new ConstantScoreScorer(new FakeWeight(), 0f, anonymizeIterator(new BitDocIdSet(set).iterator()));
|
newIterator = new ConstantScoreScorer(new FakeWeight(), 0f, ScoreMode.TOP_SCORES, anonymizeIterator(new BitDocIdSet(set).iterator()));
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
// bitSet iterator
|
// bitSet iterator
|
||||||
sets[i] = set;
|
sets[i] = set;
|
||||||
newIterator = new ConstantScoreScorer(new FakeWeight(), 0f, new BitDocIdSet(set).iterator());
|
newIterator = new ConstantScoreScorer(new FakeWeight(), 0f, ScoreMode.TOP_SCORES, new BitDocIdSet(set).iterator());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// scorer with approximation
|
// scorer with approximation
|
||||||
|
@ -352,7 +352,7 @@ public class TestConjunctionDISI extends LuceneTestCase {
|
||||||
if (random().nextBoolean()) {
|
if (random().nextBoolean()) {
|
||||||
// simple iterator
|
// simple iterator
|
||||||
sets[i] = set;
|
sets[i] = set;
|
||||||
scorers.add(new ConstantScoreScorer(new FakeWeight(), 0f, new BitDocIdSet(set).iterator()));
|
scorers.add(new ConstantScoreScorer(new FakeWeight(), 0f, ScoreMode.TOP_SCORES, new BitDocIdSet(set).iterator()));
|
||||||
} else {
|
} else {
|
||||||
// scorer with approximation
|
// scorer with approximation
|
||||||
final FixedBitSet confirmed = clearRandomBits(set);
|
final FixedBitSet confirmed = clearRandomBits(set);
|
||||||
|
@ -372,7 +372,7 @@ public class TestConjunctionDISI extends LuceneTestCase {
|
||||||
if (wrapWithScorer) {
|
if (wrapWithScorer) {
|
||||||
subConjunction = new ConjunctionScorer(new FakeWeight(), subIterators, Collections.emptyList());
|
subConjunction = new ConjunctionScorer(new FakeWeight(), subIterators, Collections.emptyList());
|
||||||
} else {
|
} else {
|
||||||
subConjunction = new ConstantScoreScorer(new FakeWeight(), 0f, ConjunctionDISI.intersectScorers(subIterators));
|
subConjunction = new ConstantScoreScorer(new FakeWeight(), 0f, ScoreMode.TOP_SCORES, ConjunctionDISI.intersectScorers(subIterators));
|
||||||
}
|
}
|
||||||
scorers.set(subSeqStart, subConjunction);
|
scorers.set(subSeqStart, subConjunction);
|
||||||
int toRemove = subSeqEnd - subSeqStart - 1;
|
int toRemove = subSeqEnd - subSeqStart - 1;
|
||||||
|
@ -382,7 +382,7 @@ public class TestConjunctionDISI extends LuceneTestCase {
|
||||||
}
|
}
|
||||||
if (scorers.size() == 1) {
|
if (scorers.size() == 1) {
|
||||||
// ConjunctionDISI needs two iterators
|
// ConjunctionDISI needs two iterators
|
||||||
scorers.add(new ConstantScoreScorer(new FakeWeight(), 0f, DocIdSetIterator.all(maxDoc)));
|
scorers.add(new ConstantScoreScorer(new FakeWeight(), 0f, ScoreMode.TOP_SCORES, DocIdSetIterator.all(maxDoc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,219 @@
|
||||||
|
/*
|
||||||
|
* 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.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.lucene.document.Document;
|
||||||
|
import org.apache.lucene.document.Field;
|
||||||
|
import org.apache.lucene.index.IndexReader;
|
||||||
|
import org.apache.lucene.index.LeafReaderContext;
|
||||||
|
import org.apache.lucene.index.RandomIndexWriter;
|
||||||
|
import org.apache.lucene.index.Term;
|
||||||
|
import org.apache.lucene.store.Directory;
|
||||||
|
import org.apache.lucene.util.LuceneTestCase;
|
||||||
|
|
||||||
|
import static org.apache.lucene.search.BooleanClause.Occur;
|
||||||
|
import static org.apache.lucene.search.DocIdSetIterator.NO_MORE_DOCS;
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
|
||||||
|
public class TestConstantScoreScorer extends LuceneTestCase {
|
||||||
|
private static final String FIELD = "f";
|
||||||
|
private static final String[] VALUES = new String[]{
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
"foo bar",
|
||||||
|
"bar foo",
|
||||||
|
"foo not bar",
|
||||||
|
"bar foo bar",
|
||||||
|
"azerty"
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final Query TERM_QUERY = new BooleanQuery.Builder()
|
||||||
|
.add(new TermQuery(new Term(FIELD, "foo")), Occur.MUST)
|
||||||
|
.add(new TermQuery(new Term(FIELD, "bar")), Occur.MUST)
|
||||||
|
.build();
|
||||||
|
private static final Query PHRASE_QUERY = new PhraseQuery(FIELD, "foo", "bar");
|
||||||
|
|
||||||
|
public void testMatching_ScoreMode_COMPLETE() throws Exception {
|
||||||
|
testMatching(ScoreMode.COMPLETE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMatching_ScoreMode_COMPLETE_NO_SCORES() throws Exception {
|
||||||
|
testMatching(ScoreMode.COMPLETE_NO_SCORES);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testMatching(ScoreMode scoreMode) throws Exception {
|
||||||
|
|
||||||
|
try (TestConstantScoreScorerIndex index = new TestConstantScoreScorerIndex()) {
|
||||||
|
int doc;
|
||||||
|
ConstantScoreScorer scorer = index.constantScoreScorer(TERM_QUERY, 1f, scoreMode);
|
||||||
|
|
||||||
|
// "foo bar" match
|
||||||
|
doc = scorer.iterator().nextDoc();
|
||||||
|
assertThat(doc, equalTo(2));
|
||||||
|
assertThat(scorer.score(), equalTo(1f));
|
||||||
|
|
||||||
|
// should not reset iterator
|
||||||
|
scorer.setMinCompetitiveScore(2f);
|
||||||
|
assertThat(scorer.docID(), equalTo(doc));
|
||||||
|
assertThat(scorer.iterator().docID(), equalTo(doc));
|
||||||
|
assertThat(scorer.score(), equalTo(1f));
|
||||||
|
|
||||||
|
// "bar foo" match
|
||||||
|
doc = scorer.iterator().nextDoc();
|
||||||
|
assertThat(doc, equalTo(3));
|
||||||
|
assertThat(scorer.score(), equalTo(1f));
|
||||||
|
|
||||||
|
// "foo not bar" match
|
||||||
|
doc = scorer.iterator().nextDoc();
|
||||||
|
assertThat(doc, equalTo(4));
|
||||||
|
assertThat(scorer.score(), equalTo(1f));
|
||||||
|
|
||||||
|
// "foo bar foo" match
|
||||||
|
doc = scorer.iterator().nextDoc();
|
||||||
|
assertThat(doc, equalTo(5));
|
||||||
|
assertThat(scorer.score(), equalTo(1f));
|
||||||
|
|
||||||
|
doc = scorer.iterator().nextDoc();
|
||||||
|
assertThat(doc, equalTo(NO_MORE_DOCS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testMatching_ScoreMode_TOP_SCORES() throws Exception {
|
||||||
|
try (TestConstantScoreScorerIndex index = new TestConstantScoreScorerIndex()) {
|
||||||
|
int doc;
|
||||||
|
ConstantScoreScorer scorer = index.constantScoreScorer(TERM_QUERY, 1f, ScoreMode.TOP_SCORES);
|
||||||
|
|
||||||
|
// "foo bar" match
|
||||||
|
doc = scorer.iterator().nextDoc();
|
||||||
|
assertThat(doc, equalTo(2));
|
||||||
|
assertThat(scorer.score(), equalTo(1f));
|
||||||
|
|
||||||
|
scorer.setMinCompetitiveScore(2f);
|
||||||
|
assertThat(scorer.docID(), equalTo(doc));
|
||||||
|
assertThat(scorer.iterator().docID(), equalTo(doc));
|
||||||
|
assertThat(scorer.score(), equalTo(1f));
|
||||||
|
|
||||||
|
doc = scorer.iterator().nextDoc();
|
||||||
|
assertThat(doc, equalTo(NO_MORE_DOCS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testTwoPhaseMatching_ScoreMode_COMPLETE() throws Exception {
|
||||||
|
testTwoPhaseMatching(ScoreMode.COMPLETE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testTwoPhaseMatching_ScoreMode_COMPLETE_NO_SCORES() throws Exception {
|
||||||
|
testTwoPhaseMatching(ScoreMode.COMPLETE_NO_SCORES);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testTwoPhaseMatching(ScoreMode scoreMode) throws Exception {
|
||||||
|
try (TestConstantScoreScorerIndex index = new TestConstantScoreScorerIndex()) {
|
||||||
|
int doc;
|
||||||
|
ConstantScoreScorer scorer = index.constantScoreScorer(PHRASE_QUERY, 1f, scoreMode);
|
||||||
|
|
||||||
|
// "foo bar" match
|
||||||
|
doc = scorer.iterator().nextDoc();
|
||||||
|
assertThat(doc, equalTo(2));
|
||||||
|
assertThat(scorer.score(), equalTo(1f));
|
||||||
|
|
||||||
|
// should not reset iterator
|
||||||
|
scorer.setMinCompetitiveScore(2f);
|
||||||
|
assertThat(scorer.docID(), equalTo(doc));
|
||||||
|
assertThat(scorer.iterator().docID(), equalTo(doc));
|
||||||
|
assertThat(scorer.score(), equalTo(1f));
|
||||||
|
|
||||||
|
// "foo not bar" will match the approximation but not the two phase iterator
|
||||||
|
|
||||||
|
// "foo bar foo" match
|
||||||
|
doc = scorer.iterator().nextDoc();
|
||||||
|
assertThat(doc, equalTo(5));
|
||||||
|
assertThat(scorer.score(), equalTo(1f));
|
||||||
|
|
||||||
|
doc = scorer.iterator().nextDoc();
|
||||||
|
assertThat(doc, equalTo(NO_MORE_DOCS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testTwoPhaseMatching_ScoreMode_TOP_SCORES() throws Exception {
|
||||||
|
try (TestConstantScoreScorerIndex index = new TestConstantScoreScorerIndex()) {
|
||||||
|
int doc;
|
||||||
|
ConstantScoreScorer scorer = index.constantScoreScorer(PHRASE_QUERY, 1f, ScoreMode.TOP_SCORES);
|
||||||
|
|
||||||
|
// "foo bar" match
|
||||||
|
doc = scorer.iterator().nextDoc();
|
||||||
|
assertThat(doc, equalTo(2));
|
||||||
|
assertThat(scorer.score(), equalTo(1f));
|
||||||
|
|
||||||
|
scorer.setMinCompetitiveScore(2f);
|
||||||
|
assertThat(scorer.docID(), equalTo(doc));
|
||||||
|
assertThat(scorer.iterator().docID(), equalTo(doc));
|
||||||
|
assertThat(scorer.score(), equalTo(1f));
|
||||||
|
|
||||||
|
doc = scorer.iterator().nextDoc();
|
||||||
|
assertThat(doc, equalTo(NO_MORE_DOCS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class TestConstantScoreScorerIndex implements AutoCloseable {
|
||||||
|
private final Directory directory;
|
||||||
|
private final RandomIndexWriter writer;
|
||||||
|
private final IndexReader reader;
|
||||||
|
|
||||||
|
TestConstantScoreScorerIndex() throws IOException {
|
||||||
|
directory = newDirectory();
|
||||||
|
|
||||||
|
writer = new RandomIndexWriter(random(), directory,
|
||||||
|
newIndexWriterConfig().setMergePolicy(newLogMergePolicy(random().nextBoolean())));
|
||||||
|
|
||||||
|
for (String VALUE : VALUES) {
|
||||||
|
Document doc = new Document();
|
||||||
|
doc.add(newTextField(FIELD, VALUE, Field.Store.YES));
|
||||||
|
writer.addDocument(doc);
|
||||||
|
}
|
||||||
|
writer.forceMerge(1);
|
||||||
|
|
||||||
|
reader = writer.getReader();
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstantScoreScorer constantScoreScorer(Query query, float score, ScoreMode scoreMode) throws IOException {
|
||||||
|
IndexSearcher searcher = newSearcher(reader);
|
||||||
|
Weight weight = searcher.createWeight(new ConstantScoreQuery(query), scoreMode, 1);
|
||||||
|
List<LeafReaderContext> leaves = searcher.getIndexReader().leaves();
|
||||||
|
|
||||||
|
assertThat(leaves.size(), equalTo(1));
|
||||||
|
|
||||||
|
LeafReaderContext context = leaves.get(0);
|
||||||
|
Scorer scorer = weight.scorer(context);
|
||||||
|
|
||||||
|
if (scorer.twoPhaseIterator() == null) {
|
||||||
|
return new ConstantScoreScorer(scorer.getWeight(), score, scoreMode, scorer.iterator());
|
||||||
|
} else {
|
||||||
|
return new ConstantScoreScorer(scorer.getWeight(), score, scoreMode, scorer.twoPhaseIterator());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws Exception {
|
||||||
|
reader.close();
|
||||||
|
directory.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1398,7 +1398,7 @@ public class TestLRUQueryCache extends LuceneTestCase {
|
||||||
@Override
|
@Override
|
||||||
public Scorer get(long leadCost) throws IOException {
|
public Scorer get(long leadCost) throws IOException {
|
||||||
scorerCreated.set(true);
|
scorerCreated.set(true);
|
||||||
return new ConstantScoreScorer(weight, boost, DocIdSetIterator.all(1));
|
return new ConstantScoreScorer(weight, boost, scoreMode, DocIdSetIterator.all(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1484,7 +1484,7 @@ public class TestLRUQueryCache extends LuceneTestCase {
|
||||||
@Override
|
@Override
|
||||||
public Scorer scorer(LeafReaderContext context) throws IOException {
|
public Scorer scorer(LeafReaderContext context) throws IOException {
|
||||||
scorerCreatedCount.incrementAndGet();
|
scorerCreatedCount.incrementAndGet();
|
||||||
return new ConstantScoreScorer(this, 1, DocIdSetIterator.all(context.reader().maxDoc()));
|
return new ConstantScoreScorer(this, 1, scoreMode, DocIdSetIterator.all(context.reader().maxDoc()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -153,7 +153,7 @@ public class TestScorerPerf extends LuceneTestCase {
|
||||||
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 {
|
||||||
return new ConstantScoreScorer(this, score(), new BitSetIterator(docs, docs.approximateCardinality()));
|
return new ConstantScoreScorer(this, score(), scoreMode, new BitSetIterator(docs, docs.approximateCardinality()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -247,7 +247,7 @@ public class TestSortRandom extends LuceneTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ConstantScoreScorer(this, score(), new BitSetIterator(bits, bits.approximateCardinality()));
|
return new ConstantScoreScorer(this, score(), scoreMode, new BitSetIterator(bits, bits.approximateCardinality()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -122,7 +122,7 @@ public class TestUsageTrackingFilterCachingPolicy extends LuceneTestCase {
|
||||||
return new ConstantScoreWeight(DummyQuery.this, boost) {
|
return new ConstantScoreWeight(DummyQuery.this, boost) {
|
||||||
@Override
|
@Override
|
||||||
public Scorer scorer(LeafReaderContext context) throws IOException {
|
public Scorer scorer(LeafReaderContext context) throws IOException {
|
||||||
return new ConstantScoreScorer(this, score(), DocIdSetIterator.all(1));
|
return new ConstantScoreScorer(this, score(), scoreMode, DocIdSetIterator.all(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -123,7 +123,7 @@ class DrillSidewaysQuery extends Query {
|
||||||
Scorer scorer = drillDowns[dim].scorer(context);
|
Scorer scorer = drillDowns[dim].scorer(context);
|
||||||
if (scorer == null) {
|
if (scorer == null) {
|
||||||
nullCount++;
|
nullCount++;
|
||||||
scorer = new ConstantScoreScorer(drillDowns[dim], 0f, DocIdSetIterator.empty());
|
scorer = new ConstantScoreScorer(drillDowns[dim], 0f, scoreMode, DocIdSetIterator.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
dims[dim] = new DrillSidewaysScorer.DocsAndCost(scorer, drillSidewaysCollectors[dim]);
|
dims[dim] = new DrillSidewaysScorer.DocsAndCost(scorer, drillSidewaysCollectors[dim]);
|
||||||
|
|
|
@ -186,7 +186,7 @@ public final class DoubleRange extends Range {
|
||||||
return 100; // TODO: use cost of range.accept()
|
return 100; // TODO: use cost of range.accept()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return new ConstantScoreScorer(this, score(), twoPhase);
|
return new ConstantScoreScorer(this, score(), scoreMode, twoPhase);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -178,7 +178,7 @@ public final class LongRange extends Range {
|
||||||
return 100; // TODO: use cost of range.accept()
|
return 100; // TODO: use cost of range.accept()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return new ConstantScoreScorer(this, score(), twoPhase);
|
return new ConstantScoreScorer(this, score(), scoreMode, twoPhase);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -726,7 +726,7 @@ public class TestDrillSideways extends FacetTestCase {
|
||||||
@Override
|
@Override
|
||||||
public Scorer scorer(LeafReaderContext context) throws IOException {
|
public Scorer scorer(LeafReaderContext context) throws IOException {
|
||||||
DocIdSetIterator approximation = DocIdSetIterator.all(context.reader().maxDoc());
|
DocIdSetIterator approximation = DocIdSetIterator.all(context.reader().maxDoc());
|
||||||
return new ConstantScoreScorer(this, score(), new TwoPhaseIterator(approximation) {
|
return new ConstantScoreScorer(this, score(), scoreMode, new TwoPhaseIterator(approximation) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches() throws IOException {
|
public boolean matches() throws IOException {
|
||||||
|
|
|
@ -80,7 +80,7 @@ public final class FunctionMatchQuery extends Query {
|
||||||
return 100; // TODO maybe DoubleValuesSource should have a matchCost?
|
return 100; // TODO maybe DoubleValuesSource should have a matchCost?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return new ConstantScoreScorer(this, score(), twoPhase);
|
return new ConstantScoreScorer(this, score(), scoreMode, twoPhase);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -151,21 +151,21 @@ abstract class LatLonShapeQuery extends Query {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** get a scorer supplier for INTERSECT queries */
|
/** get a scorer supplier for INTERSECT queries */
|
||||||
protected ScorerSupplier getIntersectScorerSupplier(LeafReader reader, PointValues values, Weight weight) throws IOException {
|
protected ScorerSupplier getIntersectScorerSupplier(LeafReader reader, PointValues values, Weight weight, ScoreMode scoreMode) throws IOException {
|
||||||
DocIdSetBuilder result = new DocIdSetBuilder(reader.maxDoc(), values, field);
|
DocIdSetBuilder result = new DocIdSetBuilder(reader.maxDoc(), values, field);
|
||||||
IntersectVisitor visitor = getSparseIntersectVisitor(result);
|
IntersectVisitor visitor = getSparseIntersectVisitor(result);
|
||||||
return new RelationScorerSupplier(values, visitor) {
|
return new RelationScorerSupplier(values, visitor) {
|
||||||
@Override
|
@Override
|
||||||
public Scorer get(long leadCost) throws IOException {
|
public Scorer get(long leadCost) throws IOException {
|
||||||
return getIntersectsScorer(LatLonShapeQuery.this, reader, weight, result, score());
|
return getIntersectsScorer(LatLonShapeQuery.this, reader, weight, result, score(), scoreMode);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** get a scorer supplier for all other queries (DISJOINT, WITHIN) */
|
/** get a scorer supplier for all other queries (DISJOINT, WITHIN) */
|
||||||
protected ScorerSupplier getScorerSupplier(LeafReader reader, PointValues values, Weight weight) throws IOException {
|
protected ScorerSupplier getScorerSupplier(LeafReader reader, PointValues values, Weight weight, ScoreMode scoreMode) throws IOException {
|
||||||
if (queryRelation == QueryRelation.INTERSECTS) {
|
if (queryRelation == QueryRelation.INTERSECTS) {
|
||||||
return getIntersectScorerSupplier(reader, values, weight);
|
return getIntersectScorerSupplier(reader, values, weight, scoreMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
FixedBitSet intersect = new FixedBitSet(reader.maxDoc());
|
FixedBitSet intersect = new FixedBitSet(reader.maxDoc());
|
||||||
|
@ -174,7 +174,7 @@ abstract class LatLonShapeQuery extends Query {
|
||||||
return new RelationScorerSupplier(values, visitor) {
|
return new RelationScorerSupplier(values, visitor) {
|
||||||
@Override
|
@Override
|
||||||
public Scorer get(long leadCost) throws IOException {
|
public Scorer get(long leadCost) throws IOException {
|
||||||
return getScorer(LatLonShapeQuery.this, weight, intersect, disjoint, score());
|
return getScorer(LatLonShapeQuery.this, weight, intersect, disjoint, score(), scoreMode);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -204,8 +204,7 @@ abstract class LatLonShapeQuery extends Query {
|
||||||
return new ScorerSupplier() {
|
return new ScorerSupplier() {
|
||||||
@Override
|
@Override
|
||||||
public Scorer get(long leadCost) throws IOException {
|
public Scorer get(long leadCost) throws IOException {
|
||||||
return new ConstantScoreScorer(weight, score(),
|
return new ConstantScoreScorer(weight, score(), scoreMode, DocIdSetIterator.all(reader.maxDoc()));
|
||||||
DocIdSetIterator.all(reader.maxDoc()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -214,7 +213,7 @@ abstract class LatLonShapeQuery extends Query {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return getScorerSupplier(reader, values, weight);
|
return getScorerSupplier(reader, values, weight, scoreMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,7 +308,7 @@ abstract class LatLonShapeQuery extends Query {
|
||||||
|
|
||||||
/** returns a Scorer for INTERSECT queries that uses a sparse bitset */
|
/** returns a Scorer for INTERSECT queries that uses a sparse bitset */
|
||||||
protected Scorer getIntersectsScorer(LatLonShapeQuery query, LeafReader reader, Weight weight,
|
protected Scorer getIntersectsScorer(LatLonShapeQuery query, LeafReader reader, Weight weight,
|
||||||
DocIdSetBuilder docIdSetBuilder, final float boost) throws IOException {
|
DocIdSetBuilder docIdSetBuilder, final float boost, ScoreMode scoreMode) throws IOException {
|
||||||
if (values.getDocCount() == reader.maxDoc()
|
if (values.getDocCount() == reader.maxDoc()
|
||||||
&& values.getDocCount() == values.size()
|
&& values.getDocCount() == values.size()
|
||||||
&& cost() > reader.maxDoc() / 2) {
|
&& cost() > reader.maxDoc() / 2) {
|
||||||
|
@ -321,17 +320,17 @@ abstract class LatLonShapeQuery extends Query {
|
||||||
int[] cost = new int[]{reader.maxDoc()};
|
int[] cost = new int[]{reader.maxDoc()};
|
||||||
values.intersect(getInverseIntersectVisitor(query, result, cost));
|
values.intersect(getInverseIntersectVisitor(query, result, cost));
|
||||||
final DocIdSetIterator iterator = new BitSetIterator(result, cost[0]);
|
final DocIdSetIterator iterator = new BitSetIterator(result, cost[0]);
|
||||||
return new ConstantScoreScorer(weight, boost, iterator);
|
return new ConstantScoreScorer(weight, boost, scoreMode, iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
values.intersect(visitor);
|
values.intersect(visitor);
|
||||||
DocIdSetIterator iterator = docIdSetBuilder.build().iterator();
|
DocIdSetIterator iterator = docIdSetBuilder.build().iterator();
|
||||||
return new ConstantScoreScorer(weight, boost, iterator);
|
return new ConstantScoreScorer(weight, boost, scoreMode, iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** returns a Scorer for all other (non INTERSECT) queries */
|
/** returns a Scorer for all other (non INTERSECT) queries */
|
||||||
protected Scorer getScorer(LatLonShapeQuery query, Weight weight,
|
protected Scorer getScorer(LatLonShapeQuery query, Weight weight,
|
||||||
FixedBitSet intersect, FixedBitSet disjoint, final float boost) throws IOException {
|
FixedBitSet intersect, FixedBitSet disjoint, final float boost, ScoreMode scoreMode) throws IOException {
|
||||||
values.intersect(visitor);
|
values.intersect(visitor);
|
||||||
DocIdSetIterator iterator;
|
DocIdSetIterator iterator;
|
||||||
if (query.queryRelation == QueryRelation.DISJOINT) {
|
if (query.queryRelation == QueryRelation.DISJOINT) {
|
||||||
|
@ -343,7 +342,7 @@ abstract class LatLonShapeQuery extends Query {
|
||||||
} else {
|
} else {
|
||||||
iterator = new BitSetIterator(intersect, cost());
|
iterator = new BitSetIterator(intersect, cost());
|
||||||
}
|
}
|
||||||
return new ConstantScoreScorer(weight, boost, iterator);
|
return new ConstantScoreScorer(weight, boost, scoreMode, iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -102,7 +102,7 @@ public class DocValuesNumbersQuery extends Query {
|
||||||
@Override
|
@Override
|
||||||
public Scorer scorer(LeafReaderContext context) throws IOException {
|
public Scorer scorer(LeafReaderContext context) throws IOException {
|
||||||
final SortedNumericDocValues values = DocValues.getSortedNumeric(context.reader(), field);
|
final SortedNumericDocValues values = DocValues.getSortedNumeric(context.reader(), field);
|
||||||
return new ConstantScoreScorer(this, score(), new TwoPhaseIterator(values) {
|
return new ConstantScoreScorer(this, score(), scoreMode, new TwoPhaseIterator(values) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches() throws IOException {
|
public boolean matches() throws IOException {
|
||||||
|
|
|
@ -184,7 +184,7 @@ public class DocValuesTermsQuery extends Query {
|
||||||
if (matchesAtLeastOneTerm == false) {
|
if (matchesAtLeastOneTerm == false) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new ConstantScoreScorer(this, score(), new TwoPhaseIterator(values) {
|
return new ConstantScoreScorer(this, score(), scoreMode, new TwoPhaseIterator(values) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches() throws IOException {
|
public boolean matches() throws IOException {
|
||||||
|
|
|
@ -595,7 +595,7 @@ public class TestTermAutomatonQuery extends LuceneTestCase {
|
||||||
//System.out.println(" acc id=" + idSource.getInt(docID) + " docID=" + docID);
|
//System.out.println(" acc id=" + idSource.getInt(docID) + " docID=" + docID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ConstantScoreScorer(this, score(), new BitSetIterator(bits, bits.approximateCardinality()));
|
return new ConstantScoreScorer(this, score(), scoreMode, new BitSetIterator(bits, bits.approximateCardinality()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -95,7 +95,7 @@ public class CompositeVerifyQuery extends Query {
|
||||||
}
|
}
|
||||||
|
|
||||||
final TwoPhaseIterator predFuncValues = predicateValueSource.iterator(context, indexQueryScorer.iterator());
|
final TwoPhaseIterator predFuncValues = predicateValueSource.iterator(context, indexQueryScorer.iterator());
|
||||||
return new ConstantScoreScorer(this, score(), predFuncValues);
|
return new ConstantScoreScorer(this, score(), scoreMode, predFuncValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -100,7 +100,7 @@ public class IntersectsRPTVerifyQuery extends Query {
|
||||||
if (result.exactDocIdSet != null) {
|
if (result.exactDocIdSet != null) {
|
||||||
// If both sets are the same, there's nothing to verify; we needn't return a TwoPhaseIterator
|
// If both sets are the same, there's nothing to verify; we needn't return a TwoPhaseIterator
|
||||||
if (result.approxDocIdSet == result.exactDocIdSet) {
|
if (result.approxDocIdSet == result.exactDocIdSet) {
|
||||||
return new ConstantScoreScorer(this, score(), approxDISI);
|
return new ConstantScoreScorer(this, score(), scoreMode, approxDISI);
|
||||||
}
|
}
|
||||||
exactIterator = result.exactDocIdSet.iterator();
|
exactIterator = result.exactDocIdSet.iterator();
|
||||||
assert exactIterator != null;
|
assert exactIterator != null;
|
||||||
|
@ -132,7 +132,7 @@ public class IntersectsRPTVerifyQuery extends Query {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return new ConstantScoreScorer(this, score(), twoPhaseIterator);
|
return new ConstantScoreScorer(this, score(), scoreMode, twoPhaseIterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -89,7 +89,7 @@ public abstract class AbstractPrefixTreeQuery extends Query {
|
||||||
if (disi == null) {
|
if (disi == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new ConstantScoreScorer(this, score(), disi);
|
return new ConstantScoreScorer(this, score(), scoreMode, disi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -140,7 +140,7 @@ public class SerializedDVStrategy extends SpatialStrategy {
|
||||||
public Scorer scorer(LeafReaderContext context) throws IOException {
|
public Scorer scorer(LeafReaderContext context) throws IOException {
|
||||||
DocIdSetIterator approximation = DocIdSetIterator.all(context.reader().maxDoc());
|
DocIdSetIterator approximation = DocIdSetIterator.all(context.reader().maxDoc());
|
||||||
TwoPhaseIterator it = predicateValueSource.iterator(context, approximation);
|
TwoPhaseIterator it = predicateValueSource.iterator(context, approximation);
|
||||||
return new ConstantScoreScorer(this, score(), it);
|
return new ConstantScoreScorer(this, score(), scoreMode, it);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -287,7 +287,7 @@ public class PointVectorStrategy extends SpatialStrategy {
|
||||||
return 100; // distance calculation can be heavy!
|
return 100; // distance calculation can be heavy!
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return new ConstantScoreScorer(this, score(), twoPhase);
|
return new ConstantScoreScorer(this, score(), scoreMode, twoPhase);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -102,7 +102,7 @@ final class PointInGeo3DShapeQuery extends Query {
|
||||||
|
|
||||||
values.intersect(new PointInShapeIntersectVisitor(result, shape, shapeBounds));
|
values.intersect(new PointInShapeIntersectVisitor(result, shape, shapeBounds));
|
||||||
|
|
||||||
return new ConstantScoreScorer(this, score(), result.build().iterator());
|
return new ConstantScoreScorer(this, score(), scoreMode, result.build().iterator());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -142,7 +142,7 @@ public final class SolrRangeQuery extends ExtendedQueryBase implements DocSetPro
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
|
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
|
||||||
return new ConstWeight(searcher, scoreMode.needsScores(), boost);
|
return new ConstWeight(searcher, scoreMode, boost);
|
||||||
/*
|
/*
|
||||||
DocSet docs = createDocSet(searcher.getIndexReader().leaves(), searcher.getIndexReader().maxDoc());
|
DocSet docs = createDocSet(searcher.getIndexReader().leaves(), searcher.getIndexReader().maxDoc());
|
||||||
SolrConstantScoreQuery csq = new SolrConstantScoreQuery( docs.getTopFilter() );
|
SolrConstantScoreQuery csq = new SolrConstantScoreQuery( docs.getTopFilter() );
|
||||||
|
@ -327,17 +327,17 @@ public final class SolrRangeQuery extends ExtendedQueryBase implements DocSetPro
|
||||||
private static final int BOOLEAN_REWRITE_TERM_COUNT_THRESHOLD = 16;
|
private static final int BOOLEAN_REWRITE_TERM_COUNT_THRESHOLD = 16;
|
||||||
|
|
||||||
final IndexSearcher searcher;
|
final IndexSearcher searcher;
|
||||||
final boolean needScores;
|
final ScoreMode scoreMode;
|
||||||
boolean checkedFilterCache;
|
boolean checkedFilterCache;
|
||||||
Filter filter;
|
Filter filter;
|
||||||
final SegState[] segStates;
|
final SegState[] segStates;
|
||||||
|
|
||||||
|
|
||||||
protected ConstWeight(IndexSearcher searcher, boolean needScores, float boost) {
|
protected ConstWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) {
|
||||||
super( SolrRangeQuery.this, boost );
|
super( SolrRangeQuery.this, boost );
|
||||||
this.searcher = searcher;
|
this.searcher = searcher;
|
||||||
this.segStates = new SegState[ searcher.getIndexReader().leaves().size() ];
|
this.segStates = new SegState[ searcher.getIndexReader().leaves().size() ];
|
||||||
this.needScores = needScores;
|
this.scoreMode = scoreMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -407,7 +407,7 @@ public final class SolrRangeQuery extends ExtendedQueryBase implements DocSetPro
|
||||||
bq.add(new TermQuery(new Term( SolrRangeQuery.this.getField(), t.term), termStates), BooleanClause.Occur.SHOULD);
|
bq.add(new TermQuery(new Term( SolrRangeQuery.this.getField(), t.term), termStates), BooleanClause.Occur.SHOULD);
|
||||||
}
|
}
|
||||||
Query q = new ConstantScoreQuery(bq.build());
|
Query q = new ConstantScoreQuery(bq.build());
|
||||||
final Weight weight = searcher.rewrite(q).createWeight(searcher, needScores ? ScoreMode.COMPLETE : ScoreMode.COMPLETE_NO_SCORES, score());
|
final Weight weight = searcher.rewrite(q).createWeight(searcher, scoreMode, score());
|
||||||
return segStates[context.ord] = new SegState(weight);
|
return segStates[context.ord] = new SegState(weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,7 +467,7 @@ public final class SolrRangeQuery extends ExtendedQueryBase implements DocSetPro
|
||||||
if (disi == null) {
|
if (disi == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new ConstantScoreScorer(this, score(), disi);
|
return new ConstantScoreScorer(this, score(), scoreMode, disi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -127,13 +127,13 @@ public abstract class Filter extends Query {
|
||||||
return 10; // TODO use cost of bits.get()
|
return 10; // TODO use cost of bits.get()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return new ConstantScoreScorer(this, 0f, twoPhase);
|
return new ConstantScoreScorer(this, 0f, scoreMode, twoPhase);
|
||||||
}
|
}
|
||||||
final DocIdSetIterator iterator = set.iterator();
|
final DocIdSetIterator iterator = set.iterator();
|
||||||
if (iterator == null) {
|
if (iterator == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new ConstantScoreScorer(this, 0f, iterator);
|
return new ConstantScoreScorer(this, 0f, scoreMode, iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -305,7 +305,7 @@ public class GraphTermsQParserPlugin extends QParserPlugin {
|
||||||
if (disi == null) {
|
if (disi == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new ConstantScoreScorer(this, score(), disi);
|
return new ConstantScoreScorer(this, score(), scoreMode, disi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -624,7 +624,7 @@ abstract class PointSetQuery extends Query implements DocSetProducer {
|
||||||
if (readerSetIterator == null) {
|
if (readerSetIterator == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new ConstantScoreScorer(this, score(), readerSetIterator);
|
return new ConstantScoreScorer(this, score(), scoreMode, readerSetIterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -39,7 +39,6 @@ import org.apache.lucene.search.Query;
|
||||||
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.Weight;
|
import org.apache.lucene.search.Weight;
|
||||||
import org.apache.lucene.search.similarities.Similarity;
|
|
||||||
import org.apache.lucene.util.Bits;
|
import org.apache.lucene.util.Bits;
|
||||||
import org.apache.lucene.util.BytesRef;
|
import org.apache.lucene.util.BytesRef;
|
||||||
import org.apache.lucene.util.FixedBitSet;
|
import org.apache.lucene.util.FixedBitSet;
|
||||||
|
@ -167,18 +166,19 @@ class JoinQuery extends Query {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
|
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
|
||||||
return new JoinQueryWeight((SolrIndexSearcher)searcher, boost);
|
return new JoinQueryWeight((SolrIndexSearcher) searcher, scoreMode, boost);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class JoinQueryWeight extends ConstantScoreWeight {
|
private class JoinQueryWeight extends ConstantScoreWeight {
|
||||||
SolrIndexSearcher fromSearcher;
|
SolrIndexSearcher fromSearcher;
|
||||||
RefCounted<SolrIndexSearcher> fromRef;
|
RefCounted<SolrIndexSearcher> fromRef;
|
||||||
SolrIndexSearcher toSearcher;
|
SolrIndexSearcher toSearcher;
|
||||||
private Similarity similarity;
|
|
||||||
ResponseBuilder rb;
|
ResponseBuilder rb;
|
||||||
|
ScoreMode scoreMode;
|
||||||
|
|
||||||
public JoinQueryWeight(SolrIndexSearcher searcher, float boost) {
|
public JoinQueryWeight(SolrIndexSearcher searcher, ScoreMode scoreMode, float boost) {
|
||||||
super(JoinQuery.this, boost);
|
super(JoinQuery.this, boost);
|
||||||
|
this.scoreMode = scoreMode;
|
||||||
this.fromSearcher = searcher;
|
this.fromSearcher = searcher;
|
||||||
SolrRequestInfo info = SolrRequestInfo.getRequestInfo();
|
SolrRequestInfo info = SolrRequestInfo.getRequestInfo();
|
||||||
if (info != null) {
|
if (info != null) {
|
||||||
|
@ -280,7 +280,7 @@ class JoinQuery extends Query {
|
||||||
if (readerSetIterator == null) {
|
if (readerSetIterator == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new ConstantScoreScorer(this, score(), readerSetIterator);
|
return new ConstantScoreScorer(this, score(), scoreMode, readerSetIterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -84,9 +84,11 @@ public class SolrConstantScoreQuery extends Query implements ExtendedQuery {
|
||||||
|
|
||||||
protected class ConstantWeight extends ConstantScoreWeight {
|
protected class ConstantWeight extends ConstantScoreWeight {
|
||||||
private Map context;
|
private Map context;
|
||||||
|
private ScoreMode scoreMode;
|
||||||
|
|
||||||
public ConstantWeight(IndexSearcher searcher, float boost) throws IOException {
|
public ConstantWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
|
||||||
super(SolrConstantScoreQuery.this, boost);
|
super(SolrConstantScoreQuery.this, boost);
|
||||||
|
this.scoreMode = scoreMode;
|
||||||
this.context = ValueSource.newContext(searcher);
|
this.context = ValueSource.newContext(searcher);
|
||||||
if (filter instanceof SolrFilter)
|
if (filter instanceof SolrFilter)
|
||||||
((SolrFilter)filter).createWeight(context, searcher);
|
((SolrFilter)filter).createWeight(context, searcher);
|
||||||
|
@ -102,7 +104,7 @@ public class SolrConstantScoreQuery extends Query implements ExtendedQuery {
|
||||||
if (iterator == null) {
|
if (iterator == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new ConstantScoreScorer(this, score(), iterator);
|
return new ConstantScoreScorer(this, score(), scoreMode, iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -114,7 +116,7 @@ public class SolrConstantScoreQuery extends Query implements ExtendedQuery {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
|
public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
|
||||||
return new SolrConstantScoreQuery.ConstantWeight(searcher, boost);
|
return new SolrConstantScoreQuery.ConstantWeight(searcher, scoreMode, boost);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Prints a user-readable version of this query. */
|
/** Prints a user-readable version of this query. */
|
||||||
|
|
|
@ -472,7 +472,7 @@ public class SolrIndexSplitter {
|
||||||
log.error("### INVALID DELS " + dels.cardinality());
|
log.error("### INVALID DELS " + dels.cardinality());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ConstantScoreScorer(this, score(), new BitSetIterator(set, set.length()));
|
return new ConstantScoreScorer(this, score(), scoreMode, new BitSetIterator(set, set.length()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -287,7 +287,7 @@ public class TestFieldCacheSortRandom extends LuceneTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ConstantScoreScorer(this, score(), new BitSetIterator(bits, bits.approximateCardinality()));
|
return new ConstantScoreScorer(this, score(), scoreMode, new BitSetIterator(bits, bits.approximateCardinality()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue