Skip to content

Support Cypher 25 SEARCH clause with in-index filtering for vector retrievers #485

@aperepel

Description

@aperepel

Summary

Neo4j 2026.01 introduced the Cypher 25 SEARCH clause with in-index filtering for vector indexes, and this is now GA in Neo4j 2026.02. The neo4j-graphrag library should adopt this new syntax in its vector retrievers (VectorRetriever, VectorCypherRetriever, HybridRetriever, HybridCypherRetriever) to unlock native filtered vector search.

Current Behavior

The retrievers currently use db.index.vector.queryNodes / db.index.vector.queryRelationships procedures. When the filters parameter is used, the documentation states:

"When using filters, the similarity search bypasses the vector index and instead utilizes an exact match algorithm."

This means filtered searches do a brute-force scan rather than using the ANN index, which doesn't scale.

Desired Behavior

Leverage the Cypher 25 SEARCH ... WHERE syntax for in-index filtering, which applies predicates inside the vector index during traversal. The index continues searching until it finds k results matching the filter, rather than finding k results and discarding non-matches (post-filtering) or bypassing the index entirely (current behavior).

New Cypher Syntax (GA in Neo4j 2026.02)

Index creation with filterable properties:

CREATE VECTOR INDEX moviePlots IF NOT EXISTS
FOR (m:Movie) ON m.embedding
WITH [m.releaseDate, m.rating]
OPTIONS { indexConfig: {
  `vector.dimensions`: 1536,
  `vector.similarity_function`: 'cosine'
}}

In-index filtered query:

MATCH (movie:Movie)
  SEARCH movie IN (
    VECTOR INDEX moviePlots
    FOR $queryVector
    WHERE movie.releaseDate > date('2000') AND movie.rating >= 7.0
    LIMIT 10
  ) SCORE AS score
RETURN movie.title, score

Key Differences from Current filters

Aspect Current filters param Cypher 25 in-index filtering
Uses ANN index No (exact match fallback) Yes
Guarantees k results No Yes (continues searching until k matches found)
Scalability O(n) scan Index-accelerated
Supported predicates Rich ($or, $in, $like, etc.) Property comparisons with AND only (>, <, >=, <=, =)

Suggested Approach

  1. Detect Neo4j version — use SEARCH clause on 2026.01+, fall back to procedures on older versions.
  2. Add index_properties parameter to vector index creation utilities so users can declare filterable properties via WITH [...].
  3. Route compatible filters through in-index filtering — when filter predicates are simple comparisons joined by AND and the target properties are declared as index properties, use SEARCH ... WHERE instead of bypassing the index.
  4. Keep the existing filters path as a fallback for complex predicates ($or, $like, $in, etc.) that in-index filtering doesn't support.

References

Related Issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions