LUCENE-8996: maxScore was sometimes missing from distributed grouped responses.

(Julien Massenet, Diego Ceccarelli, Munendra S N, Christine Poerschke)
This commit is contained in:
Christine Poerschke 2019-12-09 13:09:44 +00:00
parent 86cab79730
commit 49631ace9f
3 changed files with 23 additions and 11 deletions

View File

@ -137,6 +137,9 @@ Bug Fixes
* LUCENE-9031: UnsupportedOperationException on MatchesIterator.getQuery() (Alan Woodward, Mikhail Khludnev) * LUCENE-9031: UnsupportedOperationException on MatchesIterator.getQuery() (Alan Woodward, Mikhail Khludnev)
* LUCENE-8996: maxScore was sometimes missing from distributed grouped responses.
(Julien Massenet, Diego Ceccarelli, Munendra S N, Christine Poerschke)
Other Other
* LUCENE-8979: Code Cleanup: Use entryset for map iteration wherever possible. - Part 2 (Koen De Groote) * LUCENE-8979: Code Cleanup: Use entryset for map iteration wherever possible. - Part 2 (Koen De Groote)

View File

@ -80,6 +80,19 @@ public class TopGroups<T> {
Avg, Avg,
} }
/**
* If either value is NaN then return the other value, otherwise
* return the greater of the two values by calling Math.max.
* @param a - one value
* @param b - another value
* @return ignoring any NaN return the greater of a and b
*/
private static float nonNANmax(float a, float b) {
if (Float.isNaN(a)) return b;
if (Float.isNaN(b)) return a;
return Math.max(a, b);
}
/** Merges an array of TopGroups, for example obtained /** Merges an array of TopGroups, for example obtained
* from the second-pass collector across multiple * from the second-pass collector across multiple
* shards. Each TopGroups must have been sorted by the * shards. Each TopGroups must have been sorted by the
@ -135,12 +148,12 @@ public class TopGroups<T> {
} else { } else {
shardTopDocs = new TopFieldDocs[shardGroups.length]; shardTopDocs = new TopFieldDocs[shardGroups.length];
} }
float totalMaxScore = Float.MIN_VALUE; float totalMaxScore = Float.NaN;
for(int groupIDX=0;groupIDX<numGroups;groupIDX++) { for(int groupIDX=0;groupIDX<numGroups;groupIDX++) {
final T groupValue = shardGroups[0].groups[groupIDX].groupValue; final T groupValue = shardGroups[0].groups[groupIDX].groupValue;
//System.out.println(" merge groupValue=" + groupValue + " sortValues=" + Arrays.toString(shardGroups[0].groups[groupIDX].groupSortValues)); //System.out.println(" merge groupValue=" + groupValue + " sortValues=" + Arrays.toString(shardGroups[0].groups[groupIDX].groupSortValues));
float maxScore = Float.MIN_VALUE; float maxScore = Float.NaN;
int totalHits = 0; int totalHits = 0;
double scoreSum = 0.0; double scoreSum = 0.0;
for(int shardIDX=0;shardIDX<shardGroups.length;shardIDX++) { for(int shardIDX=0;shardIDX<shardGroups.length;shardIDX++) {
@ -174,7 +187,7 @@ public class TopGroups<T> {
shardTopDocs[shardIDX].scoreDocs[i].shardIndex = shardIDX; shardTopDocs[shardIDX].scoreDocs[i].shardIndex = shardIDX;
} }
maxScore = Math.max(maxScore, shardGroupDocs.maxScore); maxScore = nonNANmax(maxScore, shardGroupDocs.maxScore);
assert shardGroupDocs.totalHits.relation == Relation.EQUAL_TO; assert shardGroupDocs.totalHits.relation == Relation.EQUAL_TO;
totalHits += shardGroupDocs.totalHits.value; totalHits += shardGroupDocs.totalHits.value;
scoreSum += shardGroupDocs.score; scoreSum += shardGroupDocs.score;
@ -228,7 +241,7 @@ public class TopGroups<T> {
mergedScoreDocs, mergedScoreDocs,
groupValue, groupValue,
shardGroups[0].groups[groupIDX].groupSortValues); shardGroups[0].groups[groupIDX].groupSortValues);
totalMaxScore = Math.max(totalMaxScore, maxScore); totalMaxScore = nonNANmax(totalMaxScore, maxScore);
} }
if (totalGroupCount != null) { if (totalGroupCount != null) {

View File

@ -21,16 +21,12 @@ import org.apache.lucene.search.Sort;
import org.apache.lucene.search.TotalHits; import org.apache.lucene.search.TotalHits;
import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.LuceneTestCase;
import org.junit.Ignore;
public class TopGroupsTest extends LuceneTestCase { public class TopGroupsTest extends LuceneTestCase {
@Ignore // https://issues.apache.org/jira/browse/LUCENE-8996
public void testAllGroupsEmptyInSecondPass() { public void testAllGroupsEmptyInSecondPass() {
narrativeMergeTestImplementation(false, false, false, false); narrativeMergeTestImplementation(false, false, false, false);
} }
@Ignore // https://issues.apache.org/jira/browse/LUCENE-8996
public void testSomeGroupsEmptyInSecondPass() { public void testSomeGroupsEmptyInSecondPass() {
narrativeMergeTestImplementation(false, false, false, true); narrativeMergeTestImplementation(false, false, false, true);
narrativeMergeTestImplementation(false, false, true, false); narrativeMergeTestImplementation(false, false, true, false);
@ -166,13 +162,13 @@ public class TopGroupsTest extends LuceneTestCase {
{ {
assertEquals(blueGroupValue, mergedTopGroups.groups[0].groupValue); assertEquals(blueGroupValue, mergedTopGroups.groups[0].groupValue);
final float expectedBlueMaxScore = final float expectedBlueMaxScore =
(haveBlueWhale ? blueWhaleScore : (haveBlueDragonfly ? blueDragonflyScore : Float.MIN_VALUE)); (haveBlueWhale ? blueWhaleScore : (haveBlueDragonfly ? blueDragonflyScore : Float.NaN));
checkMaxScore(expectedBlueMaxScore, mergedTopGroups.groups[0].maxScore); checkMaxScore(expectedBlueMaxScore, mergedTopGroups.groups[0].maxScore);
} }
{ {
assertEquals(redGroupValue, mergedTopGroups.groups[1].groupValue); assertEquals(redGroupValue, mergedTopGroups.groups[1].groupValue);
final float expectedRedMaxScore = final float expectedRedMaxScore =
(haveRedSquirrel ? redSquirrelScore : (haveRedAnt ? redAntScore : Float.MIN_VALUE)); (haveRedSquirrel ? redSquirrelScore : (haveRedAnt ? redAntScore : Float.NaN));
checkMaxScore(expectedRedMaxScore, mergedTopGroups.groups[1].maxScore); checkMaxScore(expectedRedMaxScore, mergedTopGroups.groups[1].maxScore);
} }
@ -181,7 +177,7 @@ public class TopGroupsTest extends LuceneTestCase {
: (haveRedSquirrel ? redSquirrelScore : (haveRedSquirrel ? redSquirrelScore
: (haveBlueDragonfly ? blueDragonflyScore : (haveBlueDragonfly ? blueDragonflyScore
: (haveRedAnt ? redAntScore : (haveRedAnt ? redAntScore
: Float.MIN_VALUE)))); : Float.NaN))));
checkMaxScore(expectedMaxScore, mergedTopGroups.maxScore); checkMaxScore(expectedMaxScore, mergedTopGroups.maxScore);
} }