diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 12b058fe14e7..8fbde7a4616f 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -288,6 +288,8 @@ Bug Fixes * GITHUB#12736: Fix NullPointerException when Monitor.getQuery cannot find the requested queryId (Davis Cook) +* GITHUB#12770: Stop exploring HNSW graph if scores are not getting better. (Ben Trent) + Build --------------------- diff --git a/lucene/core/src/java/org/apache/lucene/util/hnsw/HnswGraphSearcher.java b/lucene/core/src/java/org/apache/lucene/util/hnsw/HnswGraphSearcher.java index c18c16c38f53..0135fc5a4119 100644 --- a/lucene/core/src/java/org/apache/lucene/util/hnsw/HnswGraphSearcher.java +++ b/lucene/core/src/java/org/apache/lucene/util/hnsw/HnswGraphSearcher.java @@ -174,8 +174,7 @@ private int[] findBestEntryPoint(RandomVectorScorer scorer, HnswGraph graph, lon } float friendSimilarity = scorer.score(friendOrd); visitedCount++; - if (friendSimilarity > currentScore - || (friendSimilarity == currentScore && friendOrd < currentEp)) { + if (friendSimilarity > currentScore) { currentScore = friendSimilarity; currentEp = friendOrd; foundBetter = true; @@ -243,7 +242,7 @@ void searchLevel( } float friendSimilarity = scorer.score(friendOrd); results.incVisitedCount(1); - if (friendSimilarity >= minAcceptedSimilarity) { + if (friendSimilarity > minAcceptedSimilarity) { candidates.add(friendOrd, friendSimilarity); if (acceptOrds == null || acceptOrds.get(friendOrd)) { if (results.collect(friendOrd, friendSimilarity)) { diff --git a/lucene/core/src/test/org/apache/lucene/search/BaseKnnVectorQueryTestCase.java b/lucene/core/src/test/org/apache/lucene/search/BaseKnnVectorQueryTestCase.java index 03531253abcf..d45902d3bb3c 100644 --- a/lucene/core/src/test/org/apache/lucene/search/BaseKnnVectorQueryTestCase.java +++ b/lucene/core/src/test/org/apache/lucene/search/BaseKnnVectorQueryTestCase.java @@ -281,12 +281,12 @@ public void testScoreEuclidean() throws IOException { DocIdSetIterator it = scorer.iterator(); assertEquals(3, it.cost()); - assertEquals(1, it.nextDoc()); - assertEquals(1 / 6f, scorer.score(), 0); - assertEquals(3, it.advance(3)); + assertEquals(2, it.nextDoc()); assertEquals(1 / 2f, scorer.score(), 0); + assertEquals(4, it.advance(4)); + assertEquals(1 / 6f, scorer.score(), 0); - assertEquals(NO_MORE_DOCS, it.advance(4)); + assertEquals(NO_MORE_DOCS, it.advance(5)); expectThrows(ArrayIndexOutOfBoundsException.class, scorer::score); } } @@ -384,7 +384,7 @@ public void testExplain() throws IOException { assertEquals(0, matched.getDetails().length); assertEquals("within top 3 docs", matched.getDescription()); - Explanation nomatch = searcher.explain(query, 4); + Explanation nomatch = searcher.explain(query, 1); assertFalse(nomatch.isMatch()); assertEquals(0f, nomatch.getValue()); assertEquals(0, matched.getDetails().length);