use factor in scripts, so custom score function will work correctly when it multiplies
This commit is contained in:
parent
7d0af6a345
commit
e5f2ce0fd6
|
@ -49,13 +49,23 @@ public class BoostScoreFunction implements ScoreFunction {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Explanation explain(int docId, Explanation subQueryExpl) {
|
||||
public float factor(int docId) {
|
||||
return boost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Explanation explainScore(int docId, Explanation subQueryExpl) {
|
||||
Explanation exp = new Explanation(boost * subQueryExpl.getValue(), "static boost function: product of:");
|
||||
exp.addDetail(subQueryExpl);
|
||||
exp.addDetail(new Explanation(boost, "boostFactor"));
|
||||
return exp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Explanation explainFactor(int docId) {
|
||||
return new Explanation(boost, "boostFactor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
@ -72,4 +82,9 @@ public class BoostScoreFunction implements ScoreFunction {
|
|||
public int hashCode() {
|
||||
return (boost != +0.0f ? Float.floatToIntBits(boost) : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "boost[" + boost + "]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,8 +34,6 @@ import java.util.Set;
|
|||
/**
|
||||
* A query that allows for a pluggable boost function / filter. If it matches the filter, it will
|
||||
* be boosted by the formula.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class FiltersFunctionScoreQuery extends Query {
|
||||
|
||||
|
@ -166,7 +164,7 @@ public class FiltersFunctionScoreQuery extends Query {
|
|||
DocSet docSet = DocSets.convert(reader, filterFunction.filter.getDocIdSet(reader));
|
||||
if (docSet.get(doc)) {
|
||||
filterFunction.function.setNextReader(reader);
|
||||
Explanation functionExplanation = filterFunction.function.explain(doc, subQueryExpl);
|
||||
Explanation functionExplanation = filterFunction.function.explainFactor(doc);
|
||||
float sc = getValue() * functionExplanation.getValue();
|
||||
Explanation res = new ComplexExplanation(true, sc, "custom score, product of:");
|
||||
res.addDetail(new Explanation(1.0f, "match filter: " + filterFunction.filter.toString()));
|
||||
|
@ -186,7 +184,7 @@ public class FiltersFunctionScoreQuery extends Query {
|
|||
DocSet docSet = DocSets.convert(reader, filterFunction.filter.getDocIdSet(reader));
|
||||
if (docSet.get(doc)) {
|
||||
filterFunction.function.setNextReader(reader);
|
||||
Explanation functionExplanation = filterFunction.function.explain(doc, subQueryExpl);
|
||||
Explanation functionExplanation = filterFunction.function.explainFactor(doc);
|
||||
float sc = functionExplanation.getValue();
|
||||
count++;
|
||||
total += sc;
|
||||
|
@ -221,6 +219,7 @@ public class FiltersFunctionScoreQuery extends Query {
|
|||
}
|
||||
sc *= getValue();
|
||||
Explanation res = new ComplexExplanation(true, sc, "custom score, score mode [" + scoreMode.toString().toLowerCase() + "]");
|
||||
res.addDetail(subQueryExpl);
|
||||
for (Explanation explanation : filtersExplanations) {
|
||||
res.addDetail(explanation);
|
||||
}
|
||||
|
@ -272,56 +271,58 @@ public class FiltersFunctionScoreQuery extends Query {
|
|||
@Override
|
||||
public float score() throws IOException {
|
||||
int docId = scorer.docID();
|
||||
float score = scorer.score();
|
||||
float factor = 1.0f;
|
||||
if (scoreMode == ScoreMode.First) {
|
||||
for (int i = 0; i < filterFunctions.length; i++) {
|
||||
if (docSets[i].get(docId)) {
|
||||
return subQueryWeight * filterFunctions[i].function.score(docId, score);
|
||||
factor = filterFunctions[i].function.factor(docId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (scoreMode == ScoreMode.Max) {
|
||||
float maxScore = Float.NEGATIVE_INFINITY;
|
||||
float maxFactor = Float.NEGATIVE_INFINITY;
|
||||
for (int i = 0; i < filterFunctions.length; i++) {
|
||||
if (docSets[i].get(docId)) {
|
||||
maxScore = Math.max(filterFunctions[i].function.score(docId, score), maxScore);
|
||||
maxFactor = Math.max(filterFunctions[i].function.factor(docId), maxFactor);
|
||||
}
|
||||
}
|
||||
if (maxScore != Float.NEGATIVE_INFINITY) {
|
||||
score = maxScore;
|
||||
if (maxFactor != Float.NEGATIVE_INFINITY) {
|
||||
factor = maxFactor;
|
||||
}
|
||||
} else if (scoreMode == ScoreMode.Min) {
|
||||
float minScore = Float.POSITIVE_INFINITY;
|
||||
float minFactor = Float.POSITIVE_INFINITY;
|
||||
for (int i = 0; i < filterFunctions.length; i++) {
|
||||
if (docSets[i].get(docId)) {
|
||||
minScore = Math.min(filterFunctions[i].function.score(docId, score), minScore);
|
||||
minFactor = Math.min(filterFunctions[i].function.factor(docId), minFactor);
|
||||
}
|
||||
}
|
||||
if (minScore != Float.POSITIVE_INFINITY) {
|
||||
score = minScore;
|
||||
if (minFactor != Float.POSITIVE_INFINITY) {
|
||||
factor = minFactor;
|
||||
}
|
||||
} else if (scoreMode == ScoreMode.Multiply) {
|
||||
for (int i = 0; i < filterFunctions.length; i++) {
|
||||
if (docSets[i].get(docId)) {
|
||||
factor *= filterFunctions[i].function.factor(docId);
|
||||
}
|
||||
}
|
||||
} else { // Avg / Total
|
||||
float totalScore = 0.0f;
|
||||
float multiplicativeScore = 1.0f;
|
||||
float totalFactor = 0.0f;
|
||||
int count = 0;
|
||||
for (int i = 0; i < filterFunctions.length; i++) {
|
||||
if (docSets[i].get(docId)) {
|
||||
float tempScore = filterFunctions[i].function.score(docId, score);
|
||||
totalScore += tempScore;
|
||||
multiplicativeScore *= tempScore;
|
||||
totalFactor += filterFunctions[i].function.factor(docId);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count != 0) {
|
||||
score = totalScore;
|
||||
factor = totalFactor;
|
||||
if (scoreMode == ScoreMode.Avg) {
|
||||
score /= count;
|
||||
}
|
||||
else if (scoreMode == ScoreMode.Multiply) {
|
||||
score = multiplicativeScore;
|
||||
factor /= count;
|
||||
}
|
||||
}
|
||||
}
|
||||
return subQueryWeight * score;
|
||||
float score = scorer.score();
|
||||
return subQueryWeight * score * factor;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,8 +29,6 @@ import java.util.Set;
|
|||
|
||||
/**
|
||||
* A query that allows for a pluggable boost function to be applied to it.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class FunctionScoreQuery extends Query {
|
||||
|
||||
|
@ -117,7 +115,7 @@ public class FunctionScoreQuery extends Query {
|
|||
}
|
||||
|
||||
function.setNextReader(reader);
|
||||
Explanation functionExplanation = function.explain(doc, subQueryExpl);
|
||||
Explanation functionExplanation = function.explainScore(doc, subQueryExpl);
|
||||
float sc = getValue() * functionExplanation.getValue();
|
||||
Explanation res = new ComplexExplanation(true, sc, "custom score, product of:");
|
||||
res.addDetail(functionExplanation);
|
||||
|
|
|
@ -31,5 +31,9 @@ public interface ScoreFunction {
|
|||
|
||||
float score(int docId, float subQueryScore);
|
||||
|
||||
Explanation explain(int docId, Explanation subQueryExpl);
|
||||
float factor(int docId);
|
||||
|
||||
Explanation explainScore(int docId, Explanation subQueryExpl);
|
||||
|
||||
Explanation explainFactor(int docId);
|
||||
}
|
||||
|
|
|
@ -125,13 +125,25 @@ public class CustomScoreQueryParser implements QueryParser {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Explanation explain(int docId, Explanation subQueryExpl) {
|
||||
public float factor(int docId) {
|
||||
// just the factor, so don't provide _score
|
||||
script.setNextDocId(docId);
|
||||
return script.runAsFloat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Explanation explainScore(int docId, Explanation subQueryExpl) {
|
||||
float score = score(docId, subQueryExpl.getValue());
|
||||
Explanation exp = new Explanation(score, "script score function: product of:");
|
||||
exp.addDetail(subQueryExpl);
|
||||
return exp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Explanation explainFactor(int docId) {
|
||||
return new Explanation(factor(docId), "scriptFactor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "script[" + sScript + "], params [" + params + "]";
|
||||
|
|
|
@ -164,8 +164,8 @@ public class CustomScoreSearchTests extends AbstractNodesTests {
|
|||
|
||||
SearchResponse searchResponse = client.prepareSearch("test")
|
||||
.setQuery(customFiltersScoreQuery(matchAllQuery())
|
||||
.add(termFilter("field", "value4"), "_score * 2")
|
||||
.add(termFilter("field", "value2"), "_score * 3"))
|
||||
.add(termFilter("field", "value4"), "2")
|
||||
.add(termFilter("field", "value2"), "3"))
|
||||
.setExplain(true)
|
||||
.execute().actionGet();
|
||||
|
||||
|
|
Loading…
Reference in New Issue