diff --git a/lucene/core/src/java/org/apache/lucene/search/QueryRescorer.java b/lucene/core/src/java/org/apache/lucene/search/QueryRescorer.java index 27d88504b30..80a9f4a6a3a 100644 --- a/lucene/core/src/java/org/apache/lucene/search/QueryRescorer.java +++ b/lucene/core/src/java/org/apache/lucene/search/QueryRescorer.java @@ -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 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: diff --git a/lucene/core/src/java/org/apache/lucene/search/ScoreDoc.java b/lucene/core/src/java/org/apache/lucene/search/ScoreDoc.java index a4600c974db..1546da8b8c9 100644 --- a/lucene/core/src/java/org/apache/lucene/search/ScoreDoc.java +++ b/lucene/core/src/java/org/apache/lucene/search/ScoreDoc.java @@ -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; } } diff --git a/lucene/core/src/test/org/apache/lucene/search/TestQueryRescorer.java b/lucene/core/src/test/org/apache/lucene/search/TestQueryRescorer.java index b3c1978ecaa..d2fc9ac3714 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestQueryRescorer.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestQueryRescorer.java @@ -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;