Skip to content

[integrations][vector-store][java] Apply Elasticsearch KNN filters before selecting neighbors - #1001

Merged
wenjin272 merged 1 commit into
apache:mainfrom
weiqingy:999-knn-prefilter
Aug 14, 2026
Merged

[integrations][vector-store][java] Apply Elasticsearch KNN filters before selecting neighbors#1001
wenjin272 merged 1 commit into
apache:mainfrom
weiqingy:999-knn-prefilter

Conversation

@weiqingy

Copy link
Copy Markdown
Collaborator

Linked issue: #999

Purpose of change

queryEmbedding attached its filter with post_filter, which Elasticsearch applies after the KNN phase has already selected its k nearest hits. The filter could then only discard documents from that set, and never reach matching documents that fell outside the top k. A caller asking for five documents matching user_id=alice could get none back while hundreds were indexed, whenever the nearest vectors belonged to other users.

This moves the filter into the KNN clause, so the nearest neighbors are selected from among the documents that match. get and delete already build the same filter map into a real query clause, so this also removes the divergence between the three methods.

Both filter forms are affected, since the unified filters map and a raw filter_query are merged into a single query by combineQueryJson before it is attached.

Tests

ElasticsearchVectorStoreTest#testQueryEmbeddingFiltersBeforeSelectingNeighbors indexes six documents pointing along the query vector and three orthogonal documents belonging to another user, then queries with k of 5 and a filter selecting the three. It fails with expected: <3> but was: <0> before the change and passes after, run against Elasticsearch 8.19.0.

The test uses addEmbedding with explicit vectors so the result depends only on where the filter is applied.

Note that ElasticsearchVectorStoreTest is annotated @Disabled("Should setup Elasticsearch server."), so this test does not run in CI and needs a local Elasticsearch, as with the rest of the class.

API

No signature changes. This does change observable behavior: callers passing a filter to queryEmbedding previously received at most the matching subset of the top k, and now receive up to k matching documents.

Documentation

  • doc-needed
  • doc-not-needed
  • doc-included

Was this patch authored or co-authored using generative AI tooling?

  • Yes
  • No

Generated-by: Claude Code 2.1.228 (Claude Opus 5)

…fore selecting neighbors

queryEmbedding attached its filter with post_filter, which Elasticsearch
applies after the KNN phase has already selected its k nearest hits. The
filter could then only discard documents from that set, never reach the
matching documents that fell outside the top k. A caller asking for five
documents matching user_id=alice could get none back while hundreds were
indexed, whenever the nearest vectors belonged to other users.

Move the filter into the KNN clause so the nearest neighbors are chosen
from among the matching documents. get and delete already build the same
filter map into a real query clause, so this also removes the divergence
between the three methods.

This changes observable behavior: callers passing a filter to
queryEmbedding previously received at most the matching subset of the top
k, and now receive up to k matching documents.

Generated-by: Claude Code 2.1.228 (Claude Opus 5)
@github-actions github-actions Bot added doc-included Your PR already contains the necessary documentation updates. fixVersion/0.4.0 priority/major Default priority of the PR or issue. labels Aug 12, 2026

@wenjin272 wenjin272 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing this. LGTM

@wenjin272
wenjin272 merged commit 750551f into apache:main Aug 14, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

doc-included Your PR already contains the necessary documentation updates. fixVersion/0.4.0 priority/major Default priority of the PR or issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants