mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-17 10:25:15 +00:00
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
|
@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:");
|
Explanation exp = new Explanation(boost * subQueryExpl.getValue(), "static boost function: product of:");
|
||||||
exp.addDetail(subQueryExpl);
|
exp.addDetail(subQueryExpl);
|
||||||
exp.addDetail(new Explanation(boost, "boostFactor"));
|
exp.addDetail(new Explanation(boost, "boostFactor"));
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Explanation explainFactor(int docId) {
|
||||||
|
return new Explanation(boost, "boostFactor");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
@ -72,4 +82,9 @@ public class BoostScoreFunction implements ScoreFunction {
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return (boost != +0.0f ? Float.floatToIntBits(boost) : 0);
|
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
|
* A query that allows for a pluggable boost function / filter. If it matches the filter, it will
|
||||||
* be boosted by the formula.
|
* be boosted by the formula.
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class FiltersFunctionScoreQuery extends Query {
|
public class FiltersFunctionScoreQuery extends Query {
|
||||||
|
|
||||||
@ -166,7 +164,7 @@ public class FiltersFunctionScoreQuery extends Query {
|
|||||||
DocSet docSet = DocSets.convert(reader, filterFunction.filter.getDocIdSet(reader));
|
DocSet docSet = DocSets.convert(reader, filterFunction.filter.getDocIdSet(reader));
|
||||||
if (docSet.get(doc)) {
|
if (docSet.get(doc)) {
|
||||||
filterFunction.function.setNextReader(reader);
|
filterFunction.function.setNextReader(reader);
|
||||||
Explanation functionExplanation = filterFunction.function.explain(doc, subQueryExpl);
|
Explanation functionExplanation = filterFunction.function.explainFactor(doc);
|
||||||
float sc = getValue() * functionExplanation.getValue();
|
float sc = getValue() * functionExplanation.getValue();
|
||||||
Explanation res = new ComplexExplanation(true, sc, "custom score, product of:");
|
Explanation res = new ComplexExplanation(true, sc, "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()));
|
||||||
@ -186,7 +184,7 @@ public class FiltersFunctionScoreQuery extends Query {
|
|||||||
DocSet docSet = DocSets.convert(reader, filterFunction.filter.getDocIdSet(reader));
|
DocSet docSet = DocSets.convert(reader, filterFunction.filter.getDocIdSet(reader));
|
||||||
if (docSet.get(doc)) {
|
if (docSet.get(doc)) {
|
||||||
filterFunction.function.setNextReader(reader);
|
filterFunction.function.setNextReader(reader);
|
||||||
Explanation functionExplanation = filterFunction.function.explain(doc, subQueryExpl);
|
Explanation functionExplanation = filterFunction.function.explainFactor(doc);
|
||||||
float sc = functionExplanation.getValue();
|
float sc = functionExplanation.getValue();
|
||||||
count++;
|
count++;
|
||||||
total += sc;
|
total += sc;
|
||||||
@ -221,6 +219,7 @@ public class FiltersFunctionScoreQuery extends Query {
|
|||||||
}
|
}
|
||||||
sc *= getValue();
|
sc *= getValue();
|
||||||
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);
|
||||||
for (Explanation explanation : filtersExplanations) {
|
for (Explanation explanation : filtersExplanations) {
|
||||||
res.addDetail(explanation);
|
res.addDetail(explanation);
|
||||||
}
|
}
|
||||||
@ -272,56 +271,58 @@ public class FiltersFunctionScoreQuery extends Query {
|
|||||||
@Override
|
@Override
|
||||||
public float score() throws IOException {
|
public float score() throws IOException {
|
||||||
int docId = scorer.docID();
|
int docId = scorer.docID();
|
||||||
float score = scorer.score();
|
float factor = 1.0f;
|
||||||
if (scoreMode == ScoreMode.First) {
|
if (scoreMode == ScoreMode.First) {
|
||||||
for (int i = 0; i < filterFunctions.length; i++) {
|
for (int i = 0; i < filterFunctions.length; i++) {
|
||||||
if (docSets[i].get(docId)) {
|
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) {
|
} else if (scoreMode == ScoreMode.Max) {
|
||||||
float maxScore = Float.NEGATIVE_INFINITY;
|
float maxFactor = Float.NEGATIVE_INFINITY;
|
||||||
for (int i = 0; i < filterFunctions.length; i++) {
|
for (int i = 0; i < filterFunctions.length; i++) {
|
||||||
if (docSets[i].get(docId)) {
|
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) {
|
if (maxFactor != Float.NEGATIVE_INFINITY) {
|
||||||
score = maxScore;
|
factor = maxFactor;
|
||||||
}
|
}
|
||||||
} else if (scoreMode == ScoreMode.Min) {
|
} else if (scoreMode == ScoreMode.Min) {
|
||||||
float minScore = Float.POSITIVE_INFINITY;
|
float minFactor = Float.POSITIVE_INFINITY;
|
||||||
for (int i = 0; i < filterFunctions.length; i++) {
|
for (int i = 0; i < filterFunctions.length; i++) {
|
||||||
if (docSets[i].get(docId)) {
|
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) {
|
if (minFactor != Float.POSITIVE_INFINITY) {
|
||||||
score = minScore;
|
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
|
} else { // Avg / Total
|
||||||
float totalScore = 0.0f;
|
float totalFactor = 0.0f;
|
||||||
float multiplicativeScore = 1.0f;
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int i = 0; i < filterFunctions.length; i++) {
|
for (int i = 0; i < filterFunctions.length; i++) {
|
||||||
if (docSets[i].get(docId)) {
|
if (docSets[i].get(docId)) {
|
||||||
float tempScore = filterFunctions[i].function.score(docId, score);
|
totalFactor += filterFunctions[i].function.factor(docId);
|
||||||
totalScore += tempScore;
|
|
||||||
multiplicativeScore *= tempScore;
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count != 0) {
|
if (count != 0) {
|
||||||
score = totalScore;
|
factor = totalFactor;
|
||||||
if (scoreMode == ScoreMode.Avg) {
|
if (scoreMode == ScoreMode.Avg) {
|
||||||
score /= count;
|
factor /= count;
|
||||||
}
|
|
||||||
else if (scoreMode == ScoreMode.Multiply) {
|
|
||||||
score = multiplicativeScore;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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.
|
* A query that allows for a pluggable boost function to be applied to it.
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class FunctionScoreQuery extends Query {
|
public class FunctionScoreQuery extends Query {
|
||||||
|
|
||||||
@ -117,7 +115,7 @@ public class FunctionScoreQuery extends Query {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function.setNextReader(reader);
|
function.setNextReader(reader);
|
||||||
Explanation functionExplanation = function.explain(doc, subQueryExpl);
|
Explanation functionExplanation = function.explainScore(doc, subQueryExpl);
|
||||||
float sc = getValue() * functionExplanation.getValue();
|
float sc = getValue() * 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);
|
||||||
|
@ -31,5 +31,9 @@ public interface ScoreFunction {
|
|||||||
|
|
||||||
float score(int docId, float subQueryScore);
|
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
|
@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());
|
float score = score(docId, subQueryExpl.getValue());
|
||||||
Explanation exp = new Explanation(score, "script score function: product of:");
|
Explanation exp = new Explanation(score, "script score function: product of:");
|
||||||
exp.addDetail(subQueryExpl);
|
exp.addDetail(subQueryExpl);
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Explanation explainFactor(int docId) {
|
||||||
|
return new Explanation(factor(docId), "scriptFactor");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "script[" + sScript + "], params [" + params + "]";
|
return "script[" + sScript + "], params [" + params + "]";
|
||||||
|
@ -164,8 +164,8 @@ public class CustomScoreSearchTests extends AbstractNodesTests {
|
|||||||
|
|
||||||
SearchResponse searchResponse = client.prepareSearch("test")
|
SearchResponse searchResponse = client.prepareSearch("test")
|
||||||
.setQuery(customFiltersScoreQuery(matchAllQuery())
|
.setQuery(customFiltersScoreQuery(matchAllQuery())
|
||||||
.add(termFilter("field", "value4"), "_score * 2")
|
.add(termFilter("field", "value4"), "2")
|
||||||
.add(termFilter("field", "value2"), "_score * 3"))
|
.add(termFilter("field", "value2"), "3"))
|
||||||
.setExplain(true)
|
.setExplain(true)
|
||||||
.execute().actionGet();
|
.execute().actionGet();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user