-
Notifications
You must be signed in to change notification settings - Fork 65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reusing Statement with different property values #869
Comments
Interesting question. |
Exactly. What's the cached query used for currently? |
if you render the statement a second time (you get the cached string) You could just incorporate the parameters here, but to have them, you would need to visit the AST first, which kinda defeats the purpose. Need to think about this a bit, it's at least 50% already there… If you have a good idea, happy to work on a PR. |
But wait… For what you are doing, wouldn't that work already? @Test
void withArgs() {
var movie = Cypher.node("Movie").named("n");
var statement = Cypher.match(movie.where(
movie.property("title").eq(Cypher.parameter("whatever")).or(movie.property("year").gte(Cypher.anonParameter(1999))))).returning(movie).build();
var result1 = Renderer.getDefaultRenderer().render(statement);
assertThat(result1).isSameAs(Renderer.getDefaultRenderer().render(statement));
assertThat(result1).isEqualTo("MATCH (n:`Movie` WHERE (n.title = $whatever OR n.year >= $pcdsl01)) RETURN n");
try(var driver = GraphDatabase.driver("neo4j://localhost", AuthTokens.none())) {
for(String value : List.of("value1", "value2")) {
// Get all the anonymous parameters and their values
var parameters = new HashMap<>(statement.getCatalog().getParameters());
// add all named
parameters.put("whatever", value);
// parameters are now {whatever=value1, pcdsl01=1999}
driver.executableQuery(result1)
.withParameters(parameters)
.execute();
}
}
} You just actually need to use the parameters for your properties :) |
When it's inlined like this, yes. But consider that the part creating and running the DSL query is in a separate repository. Either a custom repository implementation or SDN. for(String value : List.of("value1", "value2")) {
movieRepository.getMovie(value);
} |
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:
Usage:
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:
or
Depends on how to share the parameters between query construction and binding. I wonder what could be the most idiomatic way.
The text was updated successfully, but these errors were encountered: