Neo4j Cypher-DSL

repository·main·Indexed 42 days ago

https://github.com/neo4j/cypher-dsl

A type-safe Java library for creating Cypher queries for Neo4j 4.0+. A spin-off from Spring Data Neo4j, it models constructs based on openCypher and includes Neo4j-specific features. It provides modules for code generation (neo4j-cypher-dsl-codegen-core, neo4j-cypher-dsl-codegen-sdn6), parsing raw Cypher strings into an AST (neo4j-cypher-dsl-parser), and safe sanitization of dynamic labels and types (neo4j-cypher-dsl-schema-name-support).

Tokens
21.6K
Snippets
58
Records
127
Agent score
53%

What's inside Neo4j Cypher-DSL

  1. What is the Neo4j Cypher-DSL?

    main

    The Neo4j Cypher-DSL is a library designed for creating Cypher queries in a typesafe way on the JVM. It allows developers to construct complex graph queries using a fluent API rather than manual string concatenation, reducing errors and improving maintainability.

    Note on API Stability: Public classes within the org.neo4j.cypherdsl package that are subject to breaking changes are annotated with @API(status = EXPERIMENTAL). Use these with caution as their signatures may change in future versions.

  2. Understand the Cypher-DSL Parser TCK capabilities

    main

    The Cypher-DSL Parser Test Compatibility Kit (TCK) is used to verify the parser's ability to handle various Cypher query patterns. The parser supports complex query structures including:

    • Pattern Matching: Variable-length paths (e.g., ()-[r:R]->()){2,3}), subqueries with EXISTS, and complex relationship patterns.
    • Filtering and Predicates: WHERE clauses with temporal functions (e.g., time()), existence checks, and logical operators.
    • Aggregations and Reductions: Using reduce() for accumulating values and list comprehensions (e.g., [n in nodes(p) | n.name]).
    • Ordering and Pagination: ORDER BY (including ASC/DESC), SKIP, and LIMIT.
    • Complex Expressions: String concatenation, arithmetic within reduce, and spatial functions like point.distance().
    • Path Variables: Assigning paths to variables (e.g., MATCH p = ...).
  3. New features in Cypher-DSL 2023.4.0

    main

    Version 2023.4.0 introduced several key capabilities:

    • Literal Handling: Ability to capture parsed literals via events and retrieve literals.
    • FOREACH Support: New builder methods for FOREACH statements.
    • Namespace Improvements: All functions are now provided within the graph.* namespaces.
    • Parameter Management: A new way to fill parsed parameters with values.
  4. Understand the API visibility and internal structure

    main

    The Cypher-DSL uses @API Guardian annotations to distinguish between public and internal APIs.

    • Public API: Intended for end-users. Annotations are applied to interfaces, classes (specifically public methods and constructors), and annotations.
    • Internal API: Classes intended for internal use (e.g., for the renderer) that must be public but should not be part of the consumer-facing API. These are located in the internal package and are not exported via module-info.java.

    To prevent accidental inheritance of internal logic, any non-abstract, public class that is part of the internal API must be declared as final.

  5. How the Cypher-DSL works: AST and Rendering

    main

    The Cypher-DSL uses a builder approach to construct an Abstract Syntax Tree (AST) representing a Cypher statement. Instead of manual string concatenation, you build the query programmatically using a type-safe API that ensures only valid Cypher constructs are generated.

    To use the constructed query, the workflow is:

    1. Build the AST: Use the DSL to create an instance of org.neo4j.cypherdsl.core.Statement.
    2. Render to String: Use a Renderer to convert the Statement into a literal Java String.
    3. Execute: Pass the resulting string to any context that supports string-based Cypher queries (e.g., the Neo4j Java driver or Spring Data Neo4j's Neo4jClient).

    Note on Parameters: Generated queries use the $param format, ensuring compatibility with all current versions of Neo4j.

    // Conceptual workflow:
    // 1. Build Statement (AST)
    Statement statement = Cypher.match(...).returning(...).build();
    
    // 2. Render to String
    String cypherString = statement.render(new CypherRenderer());
    
    // 3. Execute via driver or client
    // driver.session().run(cypherString);
  6. Chain statements with YIELD clauses

    main
    Starting with version 2024.0.0, the Cypher-DSL allows you to chain statements that end with a YIELD clause. This capability enables the composition of complex queries in a more fluid and readable manner by allowing the output of one clause to be used as the starting point for subsequent operations.
  7. Understand the Cypher-DSL core package structure

    main

    The Cypher-DSL core is designed around the openCypher specification. The primary package is org.neo4j.cypherdsl.core, which also serves as the JDK module name.

    Key architectural components include:

    • org.neo4j.cypherdsl.core: The main entry point for building Cypher queries.
    • org.neo4j.cypherdsl.core.renderer: A sub-package of core responsible for converting the query structure into Cypher strings. While it is part of the core, it is architecturally isolated from other core sub-packages to maintain clean boundaries.
    • org.neo4j.cypherdsl.core.ast: Contains the Abstract Syntax Tree components.
    • org.neo4j.cypherdsl.core.utils: Contains utility classes.
  8. Use different Cypher dialects

    main

    The Cypher-DSL supports different dialects to handle syntax variations between Neo4j versions.

    • org.neo4j.cypherdsl.core.renderer.Dialect.DEFAULT: Targets Neo4j 4.4 and earlier.
    • org.neo4j.cypherdsl.core.renderer.Dialect.NEO4J_5: Targets Neo4j 5.

    Key differences in the NEO4J_5 dialect:

    • Functions.distance renders as point.distance.
    • elementId is rendered as-is.
    • EXISTS(n.property) renders as n.property IS NOT NULL.

    Compatibility Note: In the DEFAULT dialect, elementId(node) is rendered as toString(id(node)) to ensure compatibility across Neo4j 4 and 5 without deprecation warnings.

  9. Use the Neo4j 5.23 dialect to avoid deprecation warnings

    main

    Starting with version 2024.1.0, a new dialect for Neo4j 5.23 is available. This dialect is required for Neo4j versions >= 5.23 if you want to avoid deprecation warnings related to sub-query CALL statements.

    When using the DSL to build queries that involve sub-queries with CALL statements that import WITH, the DSL will automatically rewrite them into sub-queries with variable-scoped CALL clauses. You do not need to manually rewrite your queries; simply ensure you are using the correct Neo4j 5.23 dialect in your configuration.

  10. Use the Cypher 5.26 Dialect

    main

    Starting with release 2024.5.0, a new dialect named 5.26 is available.

    When this dialect is configured, the renderer prefixes all generated queries with CYPHER 5. This ensures compatibility with Neo4j 5.26 and the 2025.x main line. It also provides forward compatibility by ensuring that future Neo4j versions treat queries generated with this dialect as Cypher 5, even if newer Cypher versions are released.

  11. How the Neo4j-OGM annotation processor works

    main

    The Neo4j-OGM annotation processor generates a static metamodel for classes annotated with @NodeEntity and @RelationshipEntity. For every annotated class found, the processor generates a corresponding class in the same package with an underscore (_) appended to its name.

    Supported Annotations:

    • @NodeEntity and @RelationshipEntity (triggers generation)
    • @Relationship, @Property, @StartNode, and @EndNode (read by the processor inside the entities)

    Limitations:

    • It does not support nested classes used as @NodeEntity or @RelationshipEntity.

    Requirements:

    • Neo4j-OGM 4 must be on the classpath.
    • Cypher-DSL version 2025.0.0 or later must be on the classpath.