@@ -228,7 +228,8 @@ var (
228
228
knnOperatorOr = knnOperator ("or" )
229
229
)
230
230
231
- func createKNNQuery (req * SearchRequest , eligibleDocsMap map [int ][]index.IndexInternalID ) (
231
+ func createKNNQuery (req * SearchRequest , eligibleDocsMap map [int ][]index.IndexInternalID ,
232
+ requiresFiltering map [int ]bool ) (
232
233
query.Query , []int64 , int64 , error ) {
233
234
if requestHasKNN (req ) {
234
235
// first perform validation
@@ -245,8 +246,9 @@ func createKNNQuery(req *SearchRequest, eligibleDocsMap map[int][]index.IndexInt
245
246
knnQuery .SetK (knn .K )
246
247
knnQuery .SetBoost (knn .Boost .Value ())
247
248
knnQuery .SetParams (knn .Params )
248
- knnQuery .SetFilterQuery (knn .FilterQuery )
249
- if filterResults , exists := eligibleDocsMap [i ]; exists {
249
+ knnQuery .SetFilterQuery (knn .FilterQuery , requiresFiltering [i ])
250
+ filterResults , exists := eligibleDocsMap [i ]
251
+ if exists && requiresFiltering [i ] {
250
252
knnQuery .FilterResults = filterResults
251
253
}
252
254
subQueries = append (subQueries , knnQuery )
@@ -330,20 +332,26 @@ func (i *indexImpl) runKnnCollector(ctx context.Context, req *SearchRequest, rea
330
332
// maps the index of the KNN query in the req to the pre-filter hits aka
331
333
// eligible docs' internal IDs .
332
334
filterHitsMap := make (map [int ][]index.IndexInternalID )
335
+ // Indicates if this query requires filtering downstream
336
+ // No filtering required if it's a match all query/no filters applied.
337
+ requiresFiltering := make (map [int ]bool )
333
338
334
339
for idx , knnReq := range req .KNN {
335
340
// TODO Can use goroutines for this filter query stuff - do it if perf results
336
341
// show this to be significantly slow otherwise.
337
342
filterQ := knnReq .FilterQuery
338
- // If there are no filters here, add a match all since that will ensure that
339
- // all the live docs in the index are eligible.
340
- // TODO See if running MatchAll queries can be skipped too - if perf shows
341
- // them to be time-consuming in existing kNN tests?
342
343
if filterQ == nil {
343
- filterQ = query .NewMatchAllQuery ()
344
+ requiresFiltering [idx ] = false
345
+ }
346
+
347
+ if _ , ok := filterQ .(* query.MatchAllQuery ); ok {
348
+ requiresFiltering [idx ] = false
349
+ continue
344
350
}
345
351
346
352
if _ , ok := filterQ .(* query.MatchNoneQuery ); ok {
353
+ // Filtering required since no hits are eligible.
354
+ requiresFiltering [idx ] = true
347
355
// a match none query just means none the documents are eligible
348
356
// hence, we can save on running the query.
349
357
continue
@@ -369,10 +377,11 @@ func (i *indexImpl) runKnnCollector(ctx context.Context, req *SearchRequest, rea
369
377
for _ , docMatch := range filterHits {
370
378
filterHitsMap [idx ] = append (filterHitsMap [idx ], docMatch .IndexInternalID )
371
379
}
380
+ requiresFiltering [idx ] = true
372
381
}
373
382
374
383
// Add the filter hits when creating the kNN query
375
- KNNQuery , kArray , sumOfK , err := createKNNQuery (req , filterHitsMap )
384
+ KNNQuery , kArray , sumOfK , err := createKNNQuery (req , filterHitsMap , requiresFiltering )
376
385
if err != nil {
377
386
return nil , err
378
387
}
0 commit comments