Skip to content

Reusing Statement with different property values #869

@zakjan

Description

@zakjan

Hi,

Constructing Cypher DSL statements has a performance overhead which makes it unusable in cycles. SDN suffers from the same issue, promotes creating a new Cypher DSL statement for every call. https://docs.spring.io/spring-data/neo4j/docs/7.1.5/reference/html/#sdn-mixins.using-cypher-dsl-statements

(I know, database queries shouldn't be used in cycles to avoid N+1 query problem, but in my case it's caused by legacy Neo4j usage patterns which originate from the embedded mode. To be refactored separately. 😮‍💨)

For constructing Cypher DSL statement just once and reusing with different parameter values, currently a wrapper class is necessary:

record CachedStatement(String cypher, Map<String, Object> parameters) {}

Usage:

class CarStatements {

    private static String NAME_KEY = "name";

    private static GET_CARS_STATEMENT = getCarsStatement();

    private static Statement getCarsStatement() {
        Parameter<?> nameParameter = Cypher.parameter(NAME_KEY);

        Node car = Cypher.node("Car").named("car");

        return Cypher.match(car).where(car.property("name").eq(nameParameter)).returning(car).build();
    }

    public static CachedStatement getCars(String name) {
        return new CachedStatement(GET_CARS_STATEMENT.getCypher(), Map.of(NAME_KEY, name));
    }
}

Is it feasible to add a method to Statement for creating a new instance with copied already rendered Cypher string and binding new parameter values, so that Cypher is reused? Potential usage:

    public static Statement getCars(String name) {
        return GET_CARS_STATEMENT.withParameters(Map.of(NAME_KEY, name));
    }

or

    private static Parameter<?> NAME_PARAMETER = Cypher.parameter("name");

    public static Statement getCars(String name) {
        return GET_CARS_STATEMENT.withParameters(Map.of(NAME_PARAMETER, name));
    }

Depends on how to share the parameters between query construction and binding. I wonder what could be the most idiomatic way.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions