LUCENE-2869: remove Query.getSimilarity

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1061050 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Muir 2011-01-19 23:03:19 +00:00
parent 460fa90564
commit ede75ff9ae
21 changed files with 70 additions and 67 deletions

View File

@ -410,6 +410,10 @@ Changes in backwards compatibility policy
Similarity impls to cutover to the more general computeNorm (Robert
Muir, Mike McCandless)
* LUCENE-2869: Deprecated Query.getSimilarity: instead of using
"runtime" subclassing/delegation, subclass the Weight instead.
(Robert Muir)
* LUCENE-2674: A new idfExplain method was added to Similarity, that
accepts an incoming docFreq. If you subclass Similarity, make sure
you also override this method on upgrade. (Robert Muir, Mike

View File

@ -21,10 +21,9 @@ import java.io.IOException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.DefaultSimilarity;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Similarity;
/**
* The BoostingQuery class can be used to effectively demote results that match a given query.
* Unlike the "NOT" clause, this still selects documents that contain undesirable terms,
@ -56,10 +55,9 @@ public class BoostingQuery extends Query {
@Override
public Query rewrite(IndexReader reader) throws IOException {
BooleanQuery result = new BooleanQuery() {
@Override
public Similarity getSimilarity(IndexSearcher searcher) {
return new DefaultSimilarity() {
public Weight createWeight(IndexSearcher searcher) throws IOException {
return new BooleanWeight(searcher, false) {
@Override
public float coord(int overlap, int max) {

View File

@ -169,7 +169,7 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
public BooleanWeight(IndexSearcher searcher, boolean disableCoord)
throws IOException {
this.similarity = getSimilarity(searcher);
this.similarity = searcher.getSimilarity();
this.disableCoord = disableCoord;
weights = new ArrayList<Weight>(clauses.size());
for (int i = 0 ; i < clauses.size(); i++) {
@ -201,6 +201,9 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
return sum ;
}
public float coord(int overlap, int maxOverlap) {
return similarity.coord(overlap, maxOverlap);
}
@Override
public void normalize(float norm) {
@ -273,7 +276,7 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
sumExpl.setMatch(0 < coord ? Boolean.TRUE : Boolean.FALSE);
sumExpl.setValue(sum);
final float coordFactor = disableCoord ? 1.0f : similarity.coord(coord, maxCoord);
final float coordFactor = disableCoord ? 1.0f : coord(coord, maxCoord);
if (coordFactor == 1.0f) {
return sumExpl; // eliminate wrapper
} else {
@ -312,7 +315,7 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
// Check if we can return a BooleanScorer
if (!scorerContext.scoreDocsInOrder && scorerContext.topScorer && required.size() == 0 && prohibited.size() < 32) {
return new BooleanScorer(this, disableCoord, similarity, minNrShouldMatch, optional, prohibited, maxCoord);
return new BooleanScorer(this, disableCoord, minNrShouldMatch, optional, prohibited, maxCoord);
}
if (required.size() == 0 && optional.size() == 0) {
@ -326,7 +329,7 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
}
// Return a BooleanScorer2
return new BooleanScorer2(this, disableCoord, similarity, minNrShouldMatch, required, prohibited, optional, maxCoord);
return new BooleanScorer2(this, disableCoord, minNrShouldMatch, required, prohibited, optional, maxCoord);
}
@Override

View File

@ -22,6 +22,7 @@ import java.util.List;
import org.apache.lucene.index.IndexReader.AtomicReaderContext;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery.BooleanWeight;
/* Description from Doug Cutting (excerpted from
* LUCENE-1483):
@ -197,7 +198,7 @@ final class BooleanScorer extends Scorer {
private Bucket current;
private int doc = -1;
BooleanScorer(Weight weight, boolean disableCoord, Similarity similarity, int minNrShouldMatch,
BooleanScorer(BooleanWeight weight, boolean disableCoord, int minNrShouldMatch,
List<Scorer> optionalScorers, List<Scorer> prohibitedScorers, int maxCoord) throws IOException {
super(null, weight); // Similarity not used
this.minNrShouldMatch = minNrShouldMatch;
@ -223,7 +224,7 @@ final class BooleanScorer extends Scorer {
coordFactors = new float[optionalScorers.size() + 1];
for (int i = 0; i < coordFactors.length; i++) {
coordFactors[i] = disableCoord ? 1.0f : similarity.coord(i, maxCoord);
coordFactors[i] = disableCoord ? 1.0f : weight.coord(i, maxCoord);
}
}

View File

@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.List;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery.BooleanWeight;
/* See the description in BooleanScorer.java, comparing
* BooleanScorer & BooleanScorer2 */
@ -42,10 +43,10 @@ class BooleanScorer2 extends Scorer {
int maxCoord = 0; // to be increased for each non prohibited scorer
int nrMatchers; // to be increased by score() of match counting scorers.
void init(Similarity sim, boolean disableCoord) { // use after all scorers have been added.
void init(boolean disableCoord) { // use after all scorers have been added.
coordFactors = new float[optionalScorers.size() + requiredScorers.size() + 1];
for (int i = 0; i < coordFactors.length; i++) {
coordFactors[i] = disableCoord ? 1.0f : sim.coord(i, maxCoord);
coordFactors[i] = disableCoord ? 1.0f : ((BooleanWeight)weight).coord(i, maxCoord);
}
}
}
@ -80,7 +81,7 @@ class BooleanScorer2 extends Scorer {
* @param optional
* the list of optional scorers.
*/
public BooleanScorer2(Weight weight, boolean disableCoord, Similarity similarity, int minNrShouldMatch,
public BooleanScorer2(BooleanWeight weight, boolean disableCoord, int minNrShouldMatch,
List<Scorer> required, List<Scorer> prohibited, List<Scorer> optional, int maxCoord) throws IOException {
super(null, weight); // Similarity not used
if (minNrShouldMatch < 0) {
@ -94,8 +95,8 @@ class BooleanScorer2 extends Scorer {
requiredScorers = required;
prohibitedScorers = prohibited;
coordinator.init(similarity, disableCoord);
countingSumScorer = makeCountingSumScorer(disableCoord, similarity);
coordinator.init(disableCoord);
countingSumScorer = makeCountingSumScorer(disableCoord);
}
/** Count a scorer as a single match. */
@ -163,11 +164,10 @@ class BooleanScorer2 extends Scorer {
}
private Scorer countingConjunctionSumScorer(boolean disableCoord,
Similarity similarity,
List<Scorer> requiredScorers) throws IOException {
// each scorer from the list counted as a single matcher
final int requiredNrMatchers = requiredScorers.size();
return new ConjunctionScorer(disableCoord ? 1.0f : similarity.coord(requiredScorers.size(), requiredScorers.size()), requiredScorers) {
return new ConjunctionScorer(disableCoord ? 1.0f : ((BooleanWeight)weight).coord(requiredScorers.size(), requiredScorers.size()), requiredScorers) {
private int lastScoredDoc = -1;
// Save the score of lastScoredDoc, so that we don't compute it more than
// once in score().
@ -191,9 +191,8 @@ class BooleanScorer2 extends Scorer {
}
private Scorer dualConjunctionSumScorer(boolean disableCoord,
Similarity similarity,
Scorer req1, Scorer req2) throws IOException { // non counting.
return new ConjunctionScorer(disableCoord ? 1.0f : similarity.coord(2, 2), req1, req2);
return new ConjunctionScorer(disableCoord ? 1.0f : ((BooleanWeight)weight).coord(2, 2), req1, req2);
// All scorers match, so defaultSimilarity always has 1 as
// the coordination factor.
// Therefore the sum of the scores of two scorers
@ -203,14 +202,13 @@ class BooleanScorer2 extends Scorer {
/** Returns the scorer to be used for match counting and score summing.
* Uses requiredScorers, optionalScorers and prohibitedScorers.
*/
private Scorer makeCountingSumScorer(boolean disableCoord,
Similarity similarity) throws IOException { // each scorer counted as a single matcher
private Scorer makeCountingSumScorer(boolean disableCoord) throws IOException { // each scorer counted as a single matcher
return (requiredScorers.size() == 0)
? makeCountingSumScorerNoReq(disableCoord, similarity)
: makeCountingSumScorerSomeReq(disableCoord, similarity);
? makeCountingSumScorerNoReq(disableCoord)
: makeCountingSumScorerSomeReq(disableCoord);
}
private Scorer makeCountingSumScorerNoReq(boolean disableCoord, Similarity similarity) throws IOException { // No required scorers
private Scorer makeCountingSumScorerNoReq(boolean disableCoord) throws IOException { // No required scorers
// minNrShouldMatch optional scorers are required, but at least 1
int nrOptRequired = (minNrShouldMatch < 1) ? 1 : minNrShouldMatch;
Scorer requiredCountingSumScorer;
@ -219,26 +217,25 @@ class BooleanScorer2 extends Scorer {
else if (optionalScorers.size() == 1)
requiredCountingSumScorer = new SingleMatchScorer(optionalScorers.get(0));
else {
requiredCountingSumScorer = countingConjunctionSumScorer(disableCoord, similarity, optionalScorers);
requiredCountingSumScorer = countingConjunctionSumScorer(disableCoord, optionalScorers);
}
return addProhibitedScorers(requiredCountingSumScorer);
}
private Scorer makeCountingSumScorerSomeReq(boolean disableCoord, Similarity similarity) throws IOException { // At least one required scorer.
private Scorer makeCountingSumScorerSomeReq(boolean disableCoord) throws IOException { // At least one required scorer.
if (optionalScorers.size() == minNrShouldMatch) { // all optional scorers also required.
ArrayList<Scorer> allReq = new ArrayList<Scorer>(requiredScorers);
allReq.addAll(optionalScorers);
return addProhibitedScorers(countingConjunctionSumScorer(disableCoord, similarity, allReq));
return addProhibitedScorers(countingConjunctionSumScorer(disableCoord, allReq));
} else { // optionalScorers.size() > minNrShouldMatch, and at least one required scorer
Scorer requiredCountingSumScorer =
requiredScorers.size() == 1
? new SingleMatchScorer(requiredScorers.get(0))
: countingConjunctionSumScorer(disableCoord, similarity, requiredScorers);
: countingConjunctionSumScorer(disableCoord, requiredScorers);
if (minNrShouldMatch > 0) { // use a required disjunction scorer over the optional scorers
return addProhibitedScorers(
dualConjunctionSumScorer( // non counting
disableCoord,
similarity,
requiredCountingSumScorer,
countingDisjunctionSumScorer(
optionalScorers,

View File

@ -102,7 +102,7 @@ public class ConstantScoreQuery extends Query {
private float queryWeight;
public ConstantWeight(IndexSearcher searcher) throws IOException {
this.similarity = getSimilarity(searcher);
this.similarity = searcher.getSimilarity();
this.innerWeight = (query == null) ? null : query.createWeight(searcher);
}

View File

@ -62,7 +62,7 @@ extends Query {
@Override
public Weight createWeight(final IndexSearcher searcher) throws IOException {
final Weight weight = query.createWeight (searcher);
final Similarity similarity = query.getSimilarity(searcher);
final Similarity similarity = searcher.getSimilarity();
return new Weight() {
private float value;

View File

@ -137,7 +137,7 @@ public class MultiPhraseQuery extends Query {
public MultiPhraseWeight(IndexSearcher searcher)
throws IOException {
this.similarity = getSimilarity(searcher);
this.similarity = searcher.getSimilarity();
// compute idf
final int maxDoc = searcher.maxDoc();

View File

@ -146,7 +146,7 @@ public class PhraseQuery extends Query {
public PhraseWeight(IndexSearcher searcher)
throws IOException {
this.similarity = getSimilarity(searcher);
this.similarity = searcher.getSimilarity();
idfExp = similarity.idfExplain(terms, searcher);
idf = idfExp.getIdf();

View File

@ -98,7 +98,7 @@ public abstract class Query implements java.io.Serializable, Cloneable {
Query query = searcher.rewrite(this);
Weight weight = query.createWeight(searcher);
float sum = weight.sumOfSquaredWeights();
float norm = getSimilarity(searcher).queryNorm(sum);
float norm = searcher.getSimilarity().queryNorm(sum);
if (Float.isInfinite(norm) || Float.isNaN(norm))
norm = 1.0f;
weight.normalize(norm);
@ -124,15 +124,6 @@ public abstract class Query implements java.io.Serializable, Cloneable {
// needs to be implemented by query subclasses
throw new UnsupportedOperationException();
}
/** Expert: Returns the Similarity implementation to be used for this query.
* Subclasses may override this method to specify their own Similarity
* implementation, perhaps one that delegates through that of the Searcher.
* By default the Searcher's Similarity implementation is returned.*/
public Similarity getSimilarity(IndexSearcher searcher) {
return searcher.getSimilarity();
}
/** Returns a clone of this query. */
@Override

View File

@ -54,7 +54,7 @@ public class TermQuery extends Query {
throws IOException {
assert termStates != null : "PerReaderTermState must not be null";
this.termStates = termStates;
this.similarity = getSimilarity(searcher);
this.similarity = searcher.getSimilarity();
if (docFreq != -1) {
idfExp = similarity.idfExplain(term, searcher, docFreq);
} else {

View File

@ -189,7 +189,7 @@ public class CustomScoreQuery extends Query {
boolean qStrict;
public CustomWeight(IndexSearcher searcher) throws IOException {
this.similarity = getSimilarity(searcher);
this.similarity = searcher.getSimilarity();
this.subQueryWeight = subQuery.weight(searcher);
this.valSrcWeights = new Weight[valSrcQueries.length];
for(int i = 0; i < valSrcQueries.length; i++) {

View File

@ -69,7 +69,7 @@ public class ValueSourceQuery extends Query {
float queryWeight;
public ValueSourceWeight(IndexSearcher searcher) {
this.similarity = getSimilarity(searcher);
this.similarity = searcher.getSimilarity();
}
/*(non-Javadoc) @see org.apache.lucene.search.Weight#getQuery() */

View File

@ -106,11 +106,6 @@ public class FieldMaskingSpanQuery extends SpanQuery {
return maskedQuery.createWeight(searcher);
}
@Override
public Similarity getSimilarity(IndexSearcher searcher) {
return maskedQuery.getSimilarity(searcher);
}
@Override
public Query rewrite(IndexReader reader) throws IOException {
FieldMaskingSpanQuery clone = null;

View File

@ -42,7 +42,7 @@ public class SpanWeight extends Weight {
public SpanWeight(SpanQuery query, IndexSearcher searcher)
throws IOException {
this.similarity = query.getSimilarity(searcher);
this.similarity = searcher.getSimilarity();
this.query = query;
terms=new HashSet<Term>();

View File

@ -25,6 +25,7 @@ import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.RandomIndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanQuery.BooleanWeight;
import org.apache.lucene.store.Directory;
import org.apache.lucene.util.LuceneTestCase;
@ -68,6 +69,13 @@ public class TestBooleanScorer extends LuceneTestCase
// 'more' variable to work properly, and this test ensures that if the logic
// changes, we have a test to back it up.
Directory directory = newDirectory();
RandomIndexWriter writer = new RandomIndexWriter(random, directory);
writer.commit();
IndexReader ir = writer.getReader();
writer.close();
IndexSearcher searcher = new IndexSearcher(ir);
Similarity sim = Similarity.getDefault();
Scorer[] scorers = new Scorer[] {new Scorer(sim) {
private int doc = -1;
@ -83,10 +91,15 @@ public class TestBooleanScorer extends LuceneTestCase
}
}};
BooleanScorer bs = new BooleanScorer(null, false, sim, 1, Arrays.asList(scorers), null, scorers.length);
BooleanWeight weight = (BooleanWeight) new BooleanQuery().createWeight(searcher);
BooleanScorer bs = new BooleanScorer(weight, false, 1, Arrays.asList(scorers), null, scorers.length);
assertEquals("should have received 3000", 3000, bs.nextDoc());
assertEquals("should have received NO_MORE_DOCS", DocIdSetIterator.NO_MORE_DOCS, bs.nextDoc());
searcher.close();
ir.close();
directory.close();
}
}

View File

@ -410,20 +410,21 @@ public class TestSpans extends LuceneTestCase {
}
};
SpanNearQuery snq = new SpanNearQuery(
final Similarity oldSim = searcher.getSimilarity();
Scorer spanScorer;
try {
searcher.setSimilarity(sim);
SpanNearQuery snq = new SpanNearQuery(
new SpanQuery[] {
makeSpanTermQuery("t1"),
makeSpanTermQuery("t2") },
slop,
ordered) {
@Override
public Similarity getSimilarity(IndexSearcher s) {
return sim;
}
};
Scorer spanScorer = snq.weight(searcher).scorer(new AtomicReaderContext(new SlowMultiReaderWrapper(searcher.getIndexReader())), ScorerContext.def());
ordered);
spanScorer = snq.weight(searcher).scorer(new AtomicReaderContext(new SlowMultiReaderWrapper(searcher.getIndexReader())), ScorerContext.def());
} finally {
searcher.setSimilarity(oldSim);
}
assertTrue("first doc", spanScorer.nextDoc() != DocIdSetIterator.NO_MORE_DOCS);
assertEquals("first doc number", spanScorer.docID(), 11);
float score = spanScorer.score();

View File

@ -371,7 +371,7 @@ class SpatialDistanceQuery extends Query {
@Override
public Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException {
return new SpatialScorer(getSimilarity(searcher), context, this);
return new SpatialScorer(searcher.getSimilarity(), context, this);
}
@Override

View File

@ -61,7 +61,7 @@ public class SolrConstantScoreQuery extends ConstantScoreQuery {
private Map context;
public ConstantWeight(IndexSearcher searcher) throws IOException {
this.similarity = getSimilarity(searcher);
this.similarity = searcher.getSimilarity();
this.context = ValueSource.newContext(searcher);
if (filter instanceof SolrFilter)
((SolrFilter)filter).createWeight(context, searcher);

View File

@ -96,7 +96,7 @@ public class BoostedQuery extends Query {
if(subQueryScorer == null) {
return null;
}
return new BoostedQuery.CustomScorer(getSimilarity(searcher), context, this, subQueryScorer, boostVal);
return new BoostedQuery.CustomScorer(searcher.getSimilarity(), context, this, subQueryScorer, boostVal);
}
@Override

View File

@ -95,7 +95,7 @@ public class FunctionQuery extends Query {
@Override
public Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException {
return new AllScorer(getSimilarity(searcher), context, this);
return new AllScorer(searcher.getSimilarity(), context, this);
}
@Override