Use original order by default for same-score items rather than sorting by docId

This commit is contained in:
Andy Webb 2024-06-12 12:59:47 +01:00
parent 8c7050b428
commit 2e4dec9792
3 changed files with 24 additions and 5 deletions

View File

@ -50,6 +50,12 @@ public abstract class QueryRescorer extends Rescorer {
throws IOException {
ScoreDoc[] hits = firstPassTopDocs.scoreDocs.clone();
// record original index of each hit in its originalIndex
// NB code below relies on hits being in docId order so the order is about to be lost
for (int i = 0; i < hits.length; i++) {
hits[i].originalIndex = i;
}
Arrays.sort(hits, (a, b) -> a.doc - b.doc);
List<LeafReaderContext> leaves = searcher.getIndexReader().leaves();
@ -110,6 +116,10 @@ public abstract class QueryRescorer extends Rescorer {
return -1;
} else if (a.score < b.score) {
return 1;
} else if (a.originalIndex > b.originalIndex) {
return 1;
} else if (a.originalIndex < b.originalIndex) {
return -1;
} else {
// This subtraction can't overflow int
// because docIDs are >= 0:

View File

@ -34,6 +34,9 @@ public class ScoreDoc {
/** Only set by {@link TopDocs#merge} */
public int shardIndex;
/** Only set by {@link QueryRescorer#rescore} */
public int originalIndex;
/** Constructs a ScoreDoc. */
public ScoreDoc(int doc, float score) {
this(doc, score, -1);
@ -49,6 +52,13 @@ public class ScoreDoc {
// A convenience method for debugging.
@Override
public String toString() {
return "doc=" + doc + " score=" + score + " shardIndex=" + shardIndex;
return "doc="
+ doc
+ " score="
+ score
+ " shardIndex="
+ shardIndex
+ " originalIndex="
+ originalIndex;
}
}

View File

@ -453,8 +453,8 @@ public class TestQueryRescorer extends LuceneTestCase {
} else if (bv < av) {
return reverseInt;
} else {
// Tie break by docID, ascending
return a - b;
// use original order if scores are the same
return 0;
}
} catch (IOException ioe) {
throw new RuntimeException(ioe);
@ -464,8 +464,7 @@ public class TestQueryRescorer extends LuceneTestCase {
boolean fail = false;
for (int i = 0; i < numHits; i++) {
// System.out.println("expected=" + expected[i] + " vs " + hits2.scoreDocs[i].doc + " v=" +
// idToNum[Integer.parseInt(r.storedFields().document(expected[i]).get("id"))]);
// System.out.println("expected=" + expected[i] + " vs " + hits2.scoreDocs[i].toString());
if (expected[i].intValue() != hits2.scoreDocs[i].doc) {
// System.out.println(" diff!");
fail = true;