-
Notifications
You must be signed in to change notification settings - Fork 69
Description
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.