FunctionScore: Fix 'avg' score mode to correctly implement weighted mean.
closes #8992 closes #9004
This commit is contained in:
parent
e6a190ec58
commit
8738583de6
|
@ -177,7 +177,15 @@ public class FiltersFunctionScoreQuery extends Query {
|
||||||
}
|
}
|
||||||
// First: Gather explanations for all filters
|
// First: Gather explanations for all filters
|
||||||
List<ComplexExplanation> filterExplanations = new ArrayList<>();
|
List<ComplexExplanation> filterExplanations = new ArrayList<>();
|
||||||
|
float weightSum = 0;
|
||||||
for (FilterFunction filterFunction : filterFunctions) {
|
for (FilterFunction filterFunction : filterFunctions) {
|
||||||
|
|
||||||
|
if (filterFunction.function instanceof WeightFactorFunction) {
|
||||||
|
weightSum += ((WeightFactorFunction) filterFunction.function).getWeight();
|
||||||
|
} else {
|
||||||
|
weightSum++;
|
||||||
|
}
|
||||||
|
|
||||||
Bits docSet = DocIdSets.toSafeBits(context.reader(),
|
Bits docSet = DocIdSets.toSafeBits(context.reader(),
|
||||||
filterFunction.filter.getDocIdSet(context, context.reader().getLiveDocs()));
|
filterFunction.filter.getDocIdSet(context, context.reader().getLiveDocs()));
|
||||||
if (docSet.get(doc)) {
|
if (docSet.get(doc)) {
|
||||||
|
@ -226,15 +234,13 @@ public class FiltersFunctionScoreQuery extends Query {
|
||||||
break;
|
break;
|
||||||
default: // Avg / Total
|
default: // Avg / Total
|
||||||
double totalFactor = 0.0f;
|
double totalFactor = 0.0f;
|
||||||
int count = 0;
|
|
||||||
for (int i = 0; i < filterExplanations.size(); i++) {
|
for (int i = 0; i < filterExplanations.size(); i++) {
|
||||||
totalFactor += filterExplanations.get(i).getValue();
|
totalFactor += filterExplanations.get(i).getValue();
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
if (count != 0) {
|
if (weightSum != 0) {
|
||||||
factor = totalFactor;
|
factor = totalFactor;
|
||||||
if (scoreMode == ScoreMode.Avg) {
|
if (scoreMode == ScoreMode.Avg) {
|
||||||
factor /= count;
|
factor /= weightSum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -300,17 +306,21 @@ public class FiltersFunctionScoreQuery extends Query {
|
||||||
}
|
}
|
||||||
} else { // Avg / Total
|
} else { // Avg / Total
|
||||||
double totalFactor = 0.0f;
|
double totalFactor = 0.0f;
|
||||||
int count = 0;
|
float weightSum = 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)) {
|
||||||
totalFactor += filterFunctions[i].function.score(docId, subQueryScore);
|
totalFactor += filterFunctions[i].function.score(docId, subQueryScore);
|
||||||
count++;
|
if (filterFunctions[i].function instanceof WeightFactorFunction) {
|
||||||
|
weightSum+= ((WeightFactorFunction)filterFunctions[i].function).getWeight();
|
||||||
|
} else {
|
||||||
|
weightSum++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (count != 0) {
|
}
|
||||||
|
if (weightSum != 0) {
|
||||||
factor = totalFactor;
|
factor = totalFactor;
|
||||||
if (scoreMode == ScoreMode.Avg) {
|
if (scoreMode == ScoreMode.Avg) {
|
||||||
factor /= count;
|
factor /= weightSum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -254,8 +254,11 @@ public class FunctionScoreTests extends ElasticsearchIntegrationTest {
|
||||||
expectedScore = Float.MAX_VALUE;
|
expectedScore = Float.MAX_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float weightSum = 0;
|
||||||
|
|
||||||
for (int i = 0; i < weights.length; i++) {
|
for (int i = 0; i < weights.length; i++) {
|
||||||
double functionScore = (double) weights[i] * scores[i];
|
double functionScore = (double) weights[i] * scores[i];
|
||||||
|
weightSum += weights[i];
|
||||||
|
|
||||||
if ("avg".equals(scoreMode)) {
|
if ("avg".equals(scoreMode)) {
|
||||||
expectedScore += functionScore;
|
expectedScore += functionScore;
|
||||||
|
@ -271,7 +274,7 @@ public class FunctionScoreTests extends ElasticsearchIntegrationTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
if ("avg".equals(scoreMode)) {
|
if ("avg".equals(scoreMode)) {
|
||||||
expectedScore /= weights.length;
|
expectedScore /= weightSum;
|
||||||
}
|
}
|
||||||
return expectedScore;
|
return expectedScore;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue