Skip to content

Make it possible to extend Patience/Seeded knn queries #14838

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lucene/CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ Bug Fixes

* GITHUB#14755: Fix too many documents collected when only bool-filter condition is present. (Ke Wei)

* GITHUB#14838: Make it possible to extend Patience/Seeded knn queries (Tommaso Teofili)

Build
---------------------
* Upgrade forbiddenapis to version 3.9. (Uwe Schindler)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ public class HnswQueueSaturationCollector extends KnnCollector.Decorator {
private int previousQueueSize;
private int currentQueueSize;

HnswQueueSaturationCollector(KnnCollector delegate, double saturationThreshold, int patience) {
public HnswQueueSaturationCollector(
KnnCollector delegate, double saturationThreshold, int patience) {
super(delegate);
this.delegate = delegate;
this.previousQueueSize = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public class PatienceKnnVectorQuery extends AbstractKnnVectorQuery {
/**
* Construct a new PatienceKnnVectorQuery instance for a float vector field
*
* @param knnQuery the knn query to be seeded
* @param knnQuery the knn query to be wrapped
* @param saturationThreshold the early exit saturation threshold
* @param patience the patience parameter
* @return a new PatienceKnnVectorQuery instance
Expand All @@ -62,7 +62,7 @@ public static PatienceKnnVectorQuery fromFloatQuery(
/**
* Construct a new PatienceKnnVectorQuery instance for a float vector field
*
* @param knnQuery the knn query to be seeded
* @param knnQuery the knn query to be wrapped
* @return a new PatienceKnnVectorQuery instance
* @lucene.experimental
*/
Expand All @@ -74,7 +74,7 @@ public static PatienceKnnVectorQuery fromFloatQuery(KnnFloatVectorQuery knnQuery
/**
* Construct a new PatienceKnnVectorQuery instance for a byte vector field
*
* @param knnQuery the knn query to be seeded
* @param knnQuery the knn query to be wrapped
* @param saturationThreshold the early exit saturation threshold
* @param patience the patience parameter
* @return a new PatienceKnnVectorQuery instance
Expand Down Expand Up @@ -124,13 +124,55 @@ public static PatienceKnnVectorQuery fromSeededQuery(SeededKnnVectorQuery knnQue
}

PatienceKnnVectorQuery(
AbstractKnnVectorQuery knnQuery, double saturationThreshold, int patience) {
super(knnQuery.field, knnQuery.k, knnQuery.filter, knnQuery.searchStrategy);
AbstractKnnVectorQuery knnQuery,
String field,
int k,
Query filter,
KnnSearchStrategy searchStrategy,
double saturationThreshold,
int patience) {
super(field, k, filter, searchStrategy);
this.delegate = knnQuery;
this.saturationThreshold = saturationThreshold;
this.patience = patience;
}

public PatienceKnnVectorQuery(
SeededKnnVectorQuery knnQuery, double saturationThreshold, int patience) {
this(
knnQuery,
knnQuery.field,
knnQuery.k,
knnQuery.filter,
knnQuery.searchStrategy,
saturationThreshold,
patience);
}

public PatienceKnnVectorQuery(
KnnFloatVectorQuery knnQuery, double saturationThreshold, int patience) {
this(
knnQuery,
knnQuery.field,
knnQuery.k,
knnQuery.filter,
knnQuery.searchStrategy,
saturationThreshold,
patience);
}

public PatienceKnnVectorQuery(
KnnByteVectorQuery knnQuery, double saturationThreshold, int patience) {
this(
knnQuery,
knnQuery.field,
knnQuery.k,
knnQuery.filter,
knnQuery.searchStrategy,
saturationThreshold,
patience);
}

private static int defaultPatience(AbstractKnnVectorQuery delegate) {
return Math.max(7, (int) (delegate.k * 0.3));
}
Expand Down Expand Up @@ -243,7 +285,11 @@ public Query rewrite(IndexSearcher indexSearcher) throws IOException {
new SeededKnnVectorQuery(
seededKnnVectorQuery.delegate,
seededKnnVectorQuery.seed,
seededKnnVectorQuery.createSeedWeight(indexSearcher));
seededKnnVectorQuery.createSeedWeight(indexSearcher),
delegate.field,
delegate.k,
delegate.filter,
delegate.searchStrategy);
}
return super.rewrite(indexSearcher);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,42 @@ public static SeededKnnVectorQuery fromByteQuery(KnnByteVectorQuery knnQuery, Qu
return new SeededKnnVectorQuery(knnQuery, seed, null);
}

SeededKnnVectorQuery(AbstractKnnVectorQuery knnQuery, Query seed, Weight seedWeight) {
super(knnQuery.field, knnQuery.k, knnQuery.filter, knnQuery.searchStrategy);
SeededKnnVectorQuery(
AbstractKnnVectorQuery knnQuery,
Query seed,
Weight seedWeight,
String field,
int k,
Query filter,
KnnSearchStrategy searchStrategy) {
super(field, k, filter, searchStrategy);
this.delegate = knnQuery;
this.seed = Objects.requireNonNull(seed);
this.seedWeight = seedWeight;
}

public SeededKnnVectorQuery(KnnFloatVectorQuery knnQuery, Query seed, Weight seedWeight) {
this(
knnQuery,
seed,
seedWeight,
knnQuery.field,
knnQuery.k,
knnQuery.filter,
knnQuery.searchStrategy);
}

public SeededKnnVectorQuery(KnnByteVectorQuery knnQuery, Query seed, Weight seedWeight) {
this(
knnQuery,
seed,
seedWeight,
knnQuery.field,
knnQuery.k,
knnQuery.filter,
knnQuery.searchStrategy);
}

@Override
public String toString(String field) {
return "SeededKnnVectorQuery{"
Expand All @@ -94,7 +123,14 @@ public Query rewrite(IndexSearcher indexSearcher) throws IOException {
return super.rewrite(indexSearcher);
}
SeededKnnVectorQuery rewritten =
new SeededKnnVectorQuery(delegate, seed, createSeedWeight(indexSearcher));
new SeededKnnVectorQuery(
delegate,
seed,
createSeedWeight(indexSearcher),
delegate.field,
delegate.k,
delegate.filter,
delegate.searchStrategy);
return rewritten.rewrite(indexSearcher);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ static class AssertingSeededKnnVectorQuery extends SeededKnnVectorQuery {

public AssertingSeededKnnVectorQuery(
AbstractKnnVectorQuery query, Query seed, Weight seedWeight, AtomicInteger seedCalls) {
super(query, seed, seedWeight);
super(query, seed, seedWeight, query.field, query.k, query.filter, query.searchStrategy);
this.seedCalls = seedCalls;
}

Expand Down
Loading