Repository navigation
[FIX] Apply the metadata filter in Neptune Analytics vector search - #675
Draft
noel-improv wants to merge 3 commits into
Draft
noel-improv wants to merge 3 commits into
noel-improv wants to merge 3 commits into
Conversation
…s as valid openCypher filter_config_to_opencypher_filters compared the versioning bounds directly, so with versioning on a source built before it was enabled, which has no valid_from or valid_to, was dropped. Every other version check coalesces a missing bound; this now does the same. TEXT_MATCH_INSENSITIVE rendered source.`key`.toLower(), which is not openCypher. It now renders toLower(source.`key`).
NeptuneIndex.top_k accepted filter_config and never used it, so vector search returned the nearest nodes from the whole tenant whatever filter the caller passed. The filter now runs as a WHERE on the source the query already matches. The filter runs after the nearest-neighbour search, so a filtered call asks the index for five times top_k and keeps the first top_k that match. A filter that matches nothing returns no results without a query, as the OpenSearch and S3 Vectors indexes do. A Neptune Analytics integration test in lexical.short checks that a filtered top_k returns only the matching source, including with a case-insensitive filter. It skips on other vector stores.
…nd test an unsupported operator A graph written since versioning shipped always has valid_from and valid_to, and older graphs are upgraded by upgrade_for_versioning.py, so the coalesce only changed results on un-upgraded graphs, including what delete_sources matched. An operator the query cannot express now has a test that it raises before any query runs.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
On Neptune Analytics,
NeptuneIndex.top_kacceptedfilter_configand never used it, so vector search returned the nearest nodes from the whole tenant whatever filter the caller passed. This applies the filter in the query, as the OpenSearch, PGVector and S3 Vectors indexes do, and fixes the case-insensitive match in the shared openCypher filter builder, which the new path exposed.Changes
NeptuneIndex.top_kadds aWHEREon the source the query already matches. The filter runs after the nearest-neighbour search, so a filtered call asks for5 * top_kneighbours (FILTER_OVER_FETCH_FACTOR) and keeps the firsttop_kthat match. The docstring says a filtered call can return fewer thantop_k.[]without embedding or querying, as the S3 Vectors and OpenSearch indexes do.top_kis read withint()and floored at 1.IN,NIN,CONTAINS,ANY,ALL) now raisesValueError, as it does for PGVector and S3 Vectors. Before this change Neptune Analytics ignored the filter, so these calls used to return unfiltered results.TEXT_MATCH_INSENSITIVErenderstoLower(source.<key>)instead ofsource.<key>.toLower(), which is not openCypher.neptune_analytics_vector_filter.NeptuneAnalyticsVectorFilterinlexical.short. It runs on theneptune-graphenv-type and skips on other vector stores.Problem
Where a later step filters the results (the traversal retrievers'
FilterByMetadata), callers got fewer thantop_kresults or none. Where nothing filters later, they got results the filter should have excluded.entity_vss_provider.pyandvector_utils.pypass the filter straight through.Related issue (if any): #
Testing
pytest)Unit:
tests/unit2793 passed (the one error is the knowntest_boto3_botocore_version_alignment). Revertingneptune_vector_indexes.pyfails 6 of the new tests; revertinggraph_utils.pyfails the case-insensitive test.Integration:
lexical.shorton--env-type neptune-graph, 26 passed and 3 skipped (the two PGVector tests and the GPU reranker, as expected for that env-type).NeptuneAnalyticsVectorFilterpassed all four assertions: the unfiltered query returned chunks from all four corpus pages, the filtered query returned 3 chunks all from the filtered page, and a case-insensitive filter on the same page ran and returned the same source.MetadataFilteringQueryand the filter-injection and empty-OR safety tests also passed.Not covered live: the shortfall a selective filter can cause when its matches lie outside the
5 * top_knearest nodes, which the four-document corpus is too small to reach.Checklist
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.