lucene 4: Upgraded o.e.common.lucene.search.function package.

This commit is contained in:
Martijn van Groningen 2012-10-31 11:35:10 +01:00 committed by Shay Banon
parent 6bbe37f876
commit da551e8847
2 changed files with 59 additions and 57 deletions

View File

@ -75,13 +75,11 @@ public class FiltersFunctionScoreQuery extends Query {
final FilterFunction[] filterFunctions; final FilterFunction[] filterFunctions;
final ScoreMode scoreMode; final ScoreMode scoreMode;
final float maxBoost; final float maxBoost;
DocSet[] docSets;
public FiltersFunctionScoreQuery(Query subQuery, ScoreMode scoreMode, FilterFunction[] filterFunctions, float maxBoost) { public FiltersFunctionScoreQuery(Query subQuery, ScoreMode scoreMode, FilterFunction[] filterFunctions, float maxBoost) {
this.subQuery = subQuery; this.subQuery = subQuery;
this.scoreMode = scoreMode; this.scoreMode = scoreMode;
this.filterFunctions = filterFunctions; this.filterFunctions = filterFunctions;
this.docSets = new DocSet[filterFunctions.length];
this.maxBoost = maxBoost; this.maxBoost = maxBoost;
} }
@ -109,42 +107,39 @@ public class FiltersFunctionScoreQuery extends Query {
@Override @Override
public Weight createWeight(IndexSearcher searcher) throws IOException { public Weight createWeight(IndexSearcher searcher) throws IOException {
return new CustomBoostFactorWeight(searcher); Weight subQueryWeight = subQuery.createWeight(searcher);
return new CustomBoostFactorWeight(subQueryWeight, filterFunctions.length);
} }
class CustomBoostFactorWeight extends Weight { class CustomBoostFactorWeight extends Weight {
IndexSearcher searcher;
Weight subQueryWeight;
public CustomBoostFactorWeight(IndexSearcher searcher) throws IOException { final Weight subQueryWeight;
this.searcher = searcher; final DocSet[] docSets;
this.subQueryWeight = subQuery.weight(searcher);
public CustomBoostFactorWeight(Weight subQueryWeight, int filterFunctionLength) throws IOException {
this.subQueryWeight = subQueryWeight;
this.docSets = new DocSet[filterFunctionLength];
} }
public Query getQuery() { public Query getQuery() {
return FiltersFunctionScoreQuery.this; return FiltersFunctionScoreQuery.this;
} }
public float getValue() {
return getBoost();
}
@Override @Override
public float sumOfSquaredWeights() throws IOException { public float getValueForNormalization() throws IOException {
float sum = subQueryWeight.sumOfSquaredWeights(); float sum = subQueryWeight.getValueForNormalization();
sum *= getBoost() * getBoost(); sum *= getBoost() * getBoost();
return sum; return sum;
} }
@Override @Override
public void normalize(float norm) { public void normalize(float norm, float topLevelBoost) {
norm *= getBoost(); subQueryWeight.normalize(norm, topLevelBoost * getBoost());
subQueryWeight.normalize(norm);
} }
@Override @Override
public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer, Bits acceptDocs) throws IOException { public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer, Bits acceptDocs) throws IOException {
Scorer subQueryScorer = subQueryWeight.scorer(context, scoreDocsInOrder, false, acceptDocs); Scorer subQueryScorer = subQueryWeight.scorer(context, scoreDocsInOrder, topScorer, acceptDocs);
if (subQueryScorer == null) { if (subQueryScorer == null) {
return null; return null;
} }
@ -153,7 +148,7 @@ public class FiltersFunctionScoreQuery extends Query {
filterFunction.function.setNextReader(context); filterFunction.function.setNextReader(context);
docSets[i] = DocSets.convert(context.reader(), filterFunction.filter.getDocIdSet(context, acceptDocs)); docSets[i] = DocSets.convert(context.reader(), filterFunction.filter.getDocIdSet(context, acceptDocs));
} }
return new CustomBoostFactorScorer(getSimilarity(searcher), this, subQueryScorer, scoreMode, filterFunctions, maxBoost, docSets); return new CustomBoostFactorScorer(this, subQueryScorer, scoreMode, filterFunctions, maxBoost, docSets);
} }
@Override @Override
@ -165,15 +160,15 @@ public class FiltersFunctionScoreQuery extends Query {
if (scoreMode == ScoreMode.First) { if (scoreMode == ScoreMode.First) {
for (FilterFunction filterFunction : filterFunctions) { for (FilterFunction filterFunction : filterFunctions) {
DocSet docSet = DocSets.convert(context.reader(), filterFunction.filter.getDocIdSet(context)); DocSet docSet = DocSets.convert(context.reader(), filterFunction.filter.getDocIdSet(context, context.reader().getLiveDocs()));
if (docSet.get(doc)) { if (docSet.get(doc)) {
filterFunction.function.setNextReader(context); filterFunction.function.setNextReader(context);
Explanation functionExplanation = filterFunction.function.explainFactor(doc); Explanation functionExplanation = filterFunction.function.explainFactor(doc);
float sc = getValue() * subQueryExpl.getValue() * functionExplanation.getValue(); float sc = getBoost() * subQueryExpl.getValue() * functionExplanation.getValue();
Explanation filterExplanation = new ComplexExplanation(true, sc, "custom score, product of:"); Explanation filterExplanation = new ComplexExplanation(true, sc, "custom score, product of:");
filterExplanation.addDetail(new Explanation(1.0f, "match filter: " + filterFunction.filter.toString())); filterExplanation.addDetail(new Explanation(1.0f, "match filter: " + filterFunction.filter.toString()));
filterExplanation.addDetail(functionExplanation); filterExplanation.addDetail(functionExplanation);
filterExplanation.addDetail(new Explanation(getValue(), "queryBoost")); filterExplanation.addDetail(new Explanation(getBoost(), "queryBoost"));
// top level score = subquery.score * filter.score (this already has the query boost) // top level score = subquery.score * filter.score (this already has the query boost)
float topLevelScore = subQueryExpl.getValue() * sc; float topLevelScore = subQueryExpl.getValue() * sc;
@ -191,7 +186,7 @@ public class FiltersFunctionScoreQuery extends Query {
float min = Float.POSITIVE_INFINITY; float min = Float.POSITIVE_INFINITY;
ArrayList<Explanation> filtersExplanations = new ArrayList<Explanation>(); ArrayList<Explanation> filtersExplanations = new ArrayList<Explanation>();
for (FilterFunction filterFunction : filterFunctions) { for (FilterFunction filterFunction : filterFunctions) {
DocSet docSet = DocSets.convert(context.reader(), filterFunction.filter.getDocIdSet(context)); DocSet docSet = DocSets.convert(context.reader(), filterFunction.filter.getDocIdSet(context, context.reader().getLiveDocs()));
if (docSet.get(doc)) { if (docSet.get(doc)) {
filterFunction.function.setNextReader(context); filterFunction.function.setNextReader(context);
Explanation functionExplanation = filterFunction.function.explainFactor(doc); Explanation functionExplanation = filterFunction.function.explainFactor(doc);
@ -204,7 +199,7 @@ public class FiltersFunctionScoreQuery extends Query {
Explanation res = new ComplexExplanation(true, factor, "custom score, product of:"); Explanation res = new ComplexExplanation(true, factor, "custom score, product of:");
res.addDetail(new Explanation(1.0f, "match filter: " + filterFunction.filter.toString())); res.addDetail(new Explanation(1.0f, "match filter: " + filterFunction.filter.toString()));
res.addDetail(functionExplanation); res.addDetail(functionExplanation);
res.addDetail(new Explanation(getValue(), "queryBoost")); res.addDetail(new Explanation(getBoost(), "queryBoost"));
filtersExplanations.add(res); filtersExplanations.add(res);
} }
} }
@ -231,7 +226,7 @@ public class FiltersFunctionScoreQuery extends Query {
if (factor > maxBoost) { if (factor > maxBoost) {
factor = maxBoost; factor = maxBoost;
} }
float sc = factor * subQueryExpl.getValue() * getValue(); float sc = factor * subQueryExpl.getValue() * getBoost();
Explanation res = new ComplexExplanation(true, sc, "custom score, score mode [" + scoreMode.toString().toLowerCase() + "]"); Explanation res = new ComplexExplanation(true, sc, "custom score, score mode [" + scoreMode.toString().toLowerCase() + "]");
res.addDetail(subQueryExpl); res.addDetail(subQueryExpl);
for (Explanation explanation : filtersExplanations) { for (Explanation explanation : filtersExplanations) {
@ -241,27 +236,28 @@ public class FiltersFunctionScoreQuery extends Query {
} }
} }
float sc = getValue() * subQueryExpl.getValue(); float sc = getBoost() * subQueryExpl.getValue();
Explanation res = new ComplexExplanation(true, sc, "custom score, no filter match, product of:"); Explanation res = new ComplexExplanation(true, sc, "custom score, no filter match, product of:");
res.addDetail(subQueryExpl); res.addDetail(subQueryExpl);
res.addDetail(new Explanation(getValue(), "queryBoost")); res.addDetail(new Explanation(getBoost(), "queryBoost"));
return res; return res;
} }
} }
static class CustomBoostFactorScorer extends Scorer { static class CustomBoostFactorScorer extends Scorer {
private final float subQueryWeight;
private final float subQueryBoost;
private final Scorer scorer; private final Scorer scorer;
private final FilterFunction[] filterFunctions; private final FilterFunction[] filterFunctions;
private final ScoreMode scoreMode; private final ScoreMode scoreMode;
private final float maxBoost; private final float maxBoost;
private final DocSet[] docSets; private final DocSet[] docSets;
private CustomBoostFactorScorer(Similarity similarity, CustomBoostFactorWeight w, Scorer scorer, private CustomBoostFactorScorer(CustomBoostFactorWeight w, Scorer scorer, ScoreMode scoreMode,
ScoreMode scoreMode, FilterFunction[] filterFunctions, float maxBoost, DocSet[] docSets) throws IOException { FilterFunction[] filterFunctions, float maxBoost, DocSet[] docSets) throws IOException {
super(similarity); super(w);
this.subQueryWeight = w.getValue(); this.subQueryBoost = w.getQuery().getBoost();
this.scorer = scorer; this.scorer = scorer;
this.scoreMode = scoreMode; this.scoreMode = scoreMode;
this.filterFunctions = filterFunctions; this.filterFunctions = filterFunctions;
@ -341,7 +337,12 @@ public class FiltersFunctionScoreQuery extends Query {
factor = maxBoost; factor = maxBoost;
} }
float score = scorer.score(); float score = scorer.score();
return subQueryWeight * score * factor; return subQueryBoost * score * factor;
}
@Override
public float freq() throws IOException {
return scorer.freq();
} }
} }

View File

@ -66,47 +66,42 @@ public class FunctionScoreQuery extends Query {
@Override @Override
public Weight createWeight(IndexSearcher searcher) throws IOException { public Weight createWeight(IndexSearcher searcher) throws IOException {
return new CustomBoostFactorWeight(searcher); Weight subQueryWeight = subQuery.createWeight(searcher);
return new CustomBoostFactorWeight(subQueryWeight);
} }
class CustomBoostFactorWeight extends Weight { class CustomBoostFactorWeight extends Weight {
IndexSearcher searcher;
Weight subQueryWeight;
public CustomBoostFactorWeight(IndexSearcher searcher) throws IOException { final Weight subQueryWeight;
this.searcher = searcher;
this.subQueryWeight = subQuery.createWeight(searcher); public CustomBoostFactorWeight(Weight subQueryWeight) throws IOException {
this.subQueryWeight = subQueryWeight;
} }
public Query getQuery() { public Query getQuery() {
return FunctionScoreQuery.this; return FunctionScoreQuery.this;
} }
public float getValue() {
return getBoost();
}
@Override @Override
public float sumOfSquaredWeights() throws IOException { public float getValueForNormalization() throws IOException {
float sum = subQueryWeight.sumOfSquaredWeights(); float sum = subQueryWeight.getValueForNormalization();
sum *= getBoost() * getBoost(); sum *= getBoost() * getBoost();
return sum; return sum;
} }
@Override @Override
public void normalize(float norm) { public void normalize(float norm, float topLevelBoost) {
norm *= getBoost(); subQueryWeight.normalize(norm, topLevelBoost * getBoost());
subQueryWeight.normalize(norm);
} }
@Override @Override
public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer, Bits acceptDocs) throws IOException { public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer, Bits acceptDocs) throws IOException {
Scorer subQueryScorer = subQueryWeight.scorer(context, scoreDocsInOrder, false, acceptDocs); Scorer subQueryScorer = subQueryWeight.scorer(context, scoreDocsInOrder, topScorer, acceptDocs);
if (subQueryScorer == null) { if (subQueryScorer == null) {
return null; return null;
} }
function.setNextReader(context); function.setNextReader(context);
return new CustomBoostFactorScorer(getSimilarity(searcher), this, subQueryScorer, function); return new CustomBoostFactorScorer(this, subQueryScorer, function);
} }
@Override @Override
@ -118,23 +113,24 @@ public class FunctionScoreQuery extends Query {
function.setNextReader(context); function.setNextReader(context);
Explanation functionExplanation = function.explainScore(doc, subQueryExpl); Explanation functionExplanation = function.explainScore(doc, subQueryExpl);
float sc = getValue() * functionExplanation.getValue(); float sc = getBoost() * functionExplanation.getValue();
Explanation res = new ComplexExplanation(true, sc, "custom score, product of:"); Explanation res = new ComplexExplanation(true, sc, "custom score, product of:");
res.addDetail(functionExplanation); res.addDetail(functionExplanation);
res.addDetail(new Explanation(getValue(), "queryBoost")); res.addDetail(new Explanation(getBoost(), "queryBoost"));
return res; return res;
} }
} }
static class CustomBoostFactorScorer extends Scorer { static class CustomBoostFactorScorer extends Scorer {
private final float subQueryWeight;
private final float subQueryBoost;
private final Scorer scorer; private final Scorer scorer;
private final ScoreFunction function; private final ScoreFunction function;
private CustomBoostFactorScorer(Similarity similarity, CustomBoostFactorWeight w, Scorer scorer, ScoreFunction function) throws IOException { private CustomBoostFactorScorer(CustomBoostFactorWeight w, Scorer scorer, ScoreFunction function) throws IOException {
super(similarity); super(w);
this.subQueryWeight = w.getValue(); this.subQueryBoost = w.getQuery().getBoost();
this.scorer = scorer; this.scorer = scorer;
this.function = function; this.function = function;
} }
@ -156,7 +152,12 @@ public class FunctionScoreQuery extends Query {
@Override @Override
public float score() throws IOException { public float score() throws IOException {
return subQueryWeight * function.score(scorer.docID(), scorer.score()); return subQueryBoost * function.score(scorer.docID(), scorer.score());
}
@Override
public float freq() throws IOException {
return scorer.freq();
} }
} }