LUCENE-10351 Correct knn search failure with deleted docs (#580)

Current when doing knn search on an segment where all documents
with knn field were deleted, we get the following error:

maxSize must be > 0 and < 2147483630; got: 0
java.lang.IllegalArgumentException: maxSize must be > 0 and < 2147483630; got: 0
	at __randomizedtesting.SeedInfo.seed([43F1F124D7076A4E:1B860BFCCB9B0BB5]:0)
	at org.apache.lucene.util.LongHeap.<init>(LongHeap.java:57)
	at org.apache.lucene.util.LongHeap$1.<init>(LongHeap.java:69)
	at org.apache.lucene.util.LongHeap.create(LongHeap.java:69)
	at org.apache.lucene.util.hnsw.NeighborQueue.<init>(NeighborQueue.java:41)
	at org.apache.lucene.util.hnsw.HnswGraph.search(HnswGraph.java:105)#

This patch fixes this error and ensures empty TopDocs are returned when
knn field doesn't have any documents left.
This commit is contained in:
Mayya Sharipova 2022-01-04 15:59:30 -05:00
parent fbc8923b0a
commit 0a1cf31084
2 changed files with 10 additions and 1 deletions

View File

@ -239,6 +239,9 @@ public final class Lucene90HnswVectorsReader extends KnnVectorsReader {
if (fieldEntry == null || fieldEntry.dimension == 0) {
return null;
}
if (fieldEntry.size() == 0) {
return new TopDocs(new TotalHits(0, TotalHits.Relation.EQUAL_TO), new ScoreDoc[0]);
}
// bound k by total number of vectors to prevent oversizing data structures
k = Math.min(k, fieldEntry.size());

View File

@ -556,9 +556,15 @@ public abstract class BaseKnnVectorsFormatTestCase extends BaseIndexFileFormatTe
w.deleteDocuments(new Term("id", "0"));
w.forceMerge(1);
try (DirectoryReader r = DirectoryReader.open(w)) {
VectorValues values = getOnlyLeafReader(r).getVectorValues("v");
LeafReader leafReader = getOnlyLeafReader(r);
VectorValues values = leafReader.getVectorValues("v");
assertNotNull(values);
assertEquals(0, values.size());
// assert that knn search doesn't fail on a field with all deleted docs
TopDocs results =
leafReader.searchNearestVectors("v", randomVector(3), 1, leafReader.getLiveDocs());
assertEquals(0, results.scoreDocs.length);
}
}
}