Wolfgang-Schuetzelhofer / jcypher

Java access to Neo4J graph databases at multiple levels of abstraction
Apache License 2.0
86 stars 15 forks source link

When using a MERGE in place of CREATE, get planner error. #10

Closed bconneen closed 8 years ago

bconneen commented 8 years ago

Executing this query:

CREATE.node(applicant).label("Applicant") .property("firstName").value("John") .property("lastName").value("Smith") .property("UniqueId").value("JohnSmith");

Works fine.

If I instead try to use a MERGE:

MERGE.node(applicant).label("Applicant") .property("firstName").value("John") .property("lastName").value("Smith") .property("UniqueId").value("JohnSmith"); I get this:

---------------DB Errors: codeOrType: Neo.ClientError.Statement.InvalidSyntax message: Parameter maps cannot be used in MERGE patterns (use a literal map instead, eg. "{id: {param}.id}") (line 1, column 48 (offset: 47)) "CYPHER planner=rule MERGE (applicant1:Applicant{props_0}) CREATE (streetAddress1:Address{props_1}), (applicant1)-[:HAS_ADDRESS]->(streetAddress1), (ipAddress1:IpAddress{ip:{param_0}}), (applicant1)-[:HAS_IP]->(ipAddress1)" ^ ---------------end Errors:

QUERY

CYPHER -------------------- CYPHER planner=rule MERGE (applicant1:Applicant{firstName:'John', lastName:'Smith', UniqueId:'JohnSmith'}) CREATE (streetAddress1:Address{street:'25 WORKER WAY', city:'DANBURY', state:'CT', zip:'06810'}), (applicant1)-[:HAS_ADDRESS]->(streetAddress1), (ipAddress1:IpAddress{ip:'32.209.26.133'}), (applicant1)-[:HAS_IP]->(ipAddress1)

JSON --------------------

{ "query":"CYPHER planner=rule MERGE (applicant1:Applicant{props_0}) CREATE (streetAddress1:Address{props_1}), (applicant1)-[:HAS_ADDRESS]->(streetAddress1), (ipAddress1:IpAddress{ip:{param_0}}), (applicant1)-[:HAS_IP]->(ipAddress1)", "params":{ "props_0":{ "firstName":"John", "lastName":"Smith", "UniqueId":"JohnSmith" }, "props_1":{ "street":"25 WORKER WAY", "city":"DANBURY", "state":"CT", "zip":"06810" }, "param_0":"32.209.26.133" } }

bconneen commented 8 years ago

If I run the same Cypher query in the Web Interface is works fine:

MERGE (applicant1:Applicant{firstName:'John', lastName:'Smith', UniqueId:'JohnSmith'}) CREATE (streetAddress1:Address{street:'25 WORKER WAY', city:'DANBURY', state:'CT', zip:'06810'}), (applicant1)-[:HAS_ADDRESS]->(streetAddress1), (ipAddress1:IpAddress{ip:'32.209.26.133'}), (applicant1)-[:HAS_IP]->(ipAddress1)

Added 3 labels, created 3 nodes, set 8 properties, created 2 relationships, statement executed in 168 ms.

bconneen commented 8 years ago

I've spent some time debugging, and I think this change MIGHT fix the problem.

QueryParamSet.java: public static boolean canUseSet(WriterContext context) { if (context.currentParamOrSet instanceof QueryParamSet && context.currentClause != ClauseType.MERGE) return ((QueryParamSet)context.currentParamOrSet).canUseSet(); return false; }

It feels like we need to prevent using property sets, when using MERGE clauses. I'm not anywhere near 100% sure that this is the absolute cause.

bconneen commented 8 years ago

More details...

If I set: query.setExtractParams(false); The merge starts working. Obviously this makes all the queries slower.

Would be be possible to set the ExtractParams per "Clause"?

I still think the best alternative might be to change HOW params are extracted for merges. but I'm a Neo4J noob, so I'm not 100% sure.

Wolfgang-Schuetzelhofer commented 8 years ago

Hi Brian,

I will have a look into the problem, you have brought it perfectly to the point with your analysis. I will provide a fixes release of JCypher (3.3.1) by next week.

Best regards, Wolfgang

Wolfgang-Schuetzelhofer commented 8 years ago

Hi Brian,

release 3.3.1. containing the fix for the MERGE problem will be out on monday, April 4th.

Best regards, Wolfgang

bconneen commented 8 years ago

Thank you sir! Got a chance to try 3.3.1 tonight. (built it from source) Works perfectly. Extract params really speed up performance when running tons of queries. Doubled my performance profile for loading my dataset. Thanks for the great library and responsiveness.

Wolfgang-Schuetzelhofer commented 8 years ago

Hi Brian,

JCypher 3.3.1 has now been released.

Best regards, Wolfgang