Wolfgang-Schuetzelhofer / jcypher

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

Multiple MERGE Clauses in one query should not be concatenated #13

Closed bconneen closed 8 years ago

bconneen commented 8 years ago

First Example: When JCYPHER Concatenates multiple MERGE clauses in the Same Query

CYPHER --------------------
CYPHER planner=rule
MERGE
     (applicant:Applicant{firstName:'JONATHAN', lastName:'CONSUMER', uniqueId:'CONSUMER_JONATHAN_C5B7A862-D06B-4890-8439-A5CB00BB4DBA'}),
     (phone1:Phone{number:'4443735878'}),
     (phone1)<-[:HAS_PHONE]-(applicant),
     (phone2:Phone{number:'4443735878'}),
     (phone2)<-[:HAS_PHONE]-(applicant),
     (govId:GovId{number:'568-56-5658'}),
     (govId)<-[:HAS_GOVID]-(applicant),
     (streetAddress:Address{street:'123 MAIN ST', city:'NEWARK', state:'DE', zip:'19711', uniqueId:'123 MAIN ST_NEWARK_DE_19711'}),
     (streetAddress)<-[:HAS_ADDRESS]-(applicant),
     (blackBox1:BlackBox{value:'0400mTR4Z7'}),
     (blackBox1)<-[:HAS_BLACKBOX]-(applicant)

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

{
    "query":"CYPHER planner=rule MERGE (applicant:Applicant{firstName:{param_0}, lastName:{param_1}, uniqueId:{param_2}}), (phone1:Phone{number:{param_3}}), (phone1)<-[:HAS_PHONE]-(applicant), (phone2:Phone{number:{param_4}}), (phone2)<-[:HAS_PHONE]-(applicant), (govId:GovId{number:{param_5}}), (govId)<-[:HAS_GOVID]-(applicant), (streetAddress:Address{street:{param_6}, city:{param_7}, state:{param_8}, zip:{param_9}, uniqueId:{param_10}}), (streetAddress)<-[:HAS_ADDRESS]-(applicant), (blackBox1:BlackBox{value:{param_11}}), (blackBox1)<-[:HAS_BLACKBOX]-(applicant)",
    "params":{
        "param_0":"JONATHAN",
        "param_1":"CONSUMER",
        "param_2":"CONSUMER_JONATHAN_C5B7A862-D06B-4890-8439-A5CB00BB4DBA",
        "param_3":"4443735878",
        "param_4":"4443735878",
        "param_5":"568-56-5658",
        "param_6":"123 MAIN ST",
        "param_7":"NEWARK",
        "param_8":"DE",
        "param_9":"19711",
        "param_10":"123 MAIN ST_NEWARK_DE_19711",
        "param_11":"0400mTR4Z7"
    }
}

---------------General Errors:
---------------DB Errors:
codeOrType: Neo.ClientError.Statement.InvalidSyntax
message: Invalid input ',': expected whitespace, a relationship pattern, ON, LOAD CSV, START, MATCH, UNWIND, MERGE, CREATE, SET, DELETE, REMOVE, FOREACH, WITH, RETURN, UNION, ';' or end of input (line 1, column 109 (offset: 108))
"MERGE (applicant:Applicant{firstName:{param_0}, lastName:{param_1}, uniqueId:{param_2}}), (phone1:Phone{number:{param_3}}), (phone1)<-[:HAS_PHONE]-(applicant), (phone2:Phone{number:{param_4}}), (phone2)<-[:HAS_PHONE]-(applicant), (govId:GovId{number:{param_5}}), (govId)<-[:HAS_GOVID]-(applicant), (streetAddress:Address{street:{param_6}, city:{param_7}, state:{param_8}, zip:{param_9}, uniqueId:{param_10}}), (streetAddress)<-[:HAS_ADDRESS]-(applicant), (blackBox1:BlackBox{value:{param_11}}), (blackBox1)<-[:HAS_BLACKBOX]-(applicant)"
                                                                                                             ^
---------------end Errors:

Second Example: When I modify ContextWriter.java to not concatenate MERGE clauses.

CYPHER --------------------
CYPHER planner=rule
MERGE
     (applicant:Applicant{firstName:'JONATHAN', lastName:'CONSUMER', uniqueId:'CONSUMER_JONATHAN_C5B7A862-D06B-4890-8439-A5CB00BB4DBA'})
MERGE
     (phone1:Phone{number:'4443735878'})
MERGE
     (phone1)<-[:HAS_PHONE]-(applicant)
MERGE
     (phone2:Phone{number:'4443735878'})
MERGE
     (phone2)<-[:HAS_PHONE]-(applicant)
MERGE
     (govId:GovId{number:'568-56-5658'})
MERGE
     (govId)<-[:HAS_GOVID]-(applicant)
MERGE
     (streetAddress:Address{street:'123 MAIN ST', city:'NEWARK', state:'DE', zip:'19711', uniqueId:'123 MAIN ST_NEWARK_DE_19711'})
MERGE
     (streetAddress)<-[:HAS_ADDRESS]-(applicant)
MERGE
     (blackBox1:BlackBox{value:'0400mTR4Z7'})
MERGE
     (blackBox1)<-[:HAS_BLACKBOX]-(applicant)

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

{
    "query":"CYPHER planner=rule MERGE (applicant:Applicant{firstName:{param_0}, lastName:{param_1}, uniqueId:{param_2}}) MERGE (phone1:Phone{number:{param_3}}) MERGE (phone1)<-[:HAS_PHONE]-(applicant) MERGE (phone2:Phone{number:{param_4}}) MERGE (phone2)<-[:HAS_PHONE]-(applicant) MERGE (govId:GovId{number:{param_5}}) MERGE (govId)<-[:HAS_GOVID]-(applicant) MERGE (streetAddress:Address{street:{param_6}, city:{param_7}, state:{param_8}, zip:{param_9}, uniqueId:{param_10}}) MERGE (streetAddress)<-[:HAS_ADDRESS]-(applicant) MERGE (blackBox1:BlackBox{value:{param_11}}) MERGE (blackBox1)<-[:HAS_BLACKBOX]-(applicant)",
    "params":{
        "param_0":"JONATHAN",
        "param_1":"CONSUMER",
        "param_2":"CONSUMER_JONATHAN_C5B7A862-D06B-4890-8439-A5CB00BB4DBA",
        "param_3":"4443735878",
        "param_4":"4443735878",
        "param_5":"568-56-5658",
        "param_6":"123 MAIN ST",
        "param_7":"NEWARK",
        "param_8":"DE",
        "param_9":"19711",
        "param_10":"123 MAIN ST_NEWARK_DE_19711",
        "param_11":"0400mTR4Z7"
    }
}

Just did this to test it:

        /*** MERGE CLAUSE **************************************/
        else if (clauseType == ClauseType.MERGE) {
            if (true || context.previousClause != ClauseType.MERGE) { // otherwise concat multiple merges
Wolfgang-Schuetzelhofer commented 8 years ago

Hi Brian, to avoid concatenating consecutive clauses of same type (not only MERGE clauses), you insert a SEPERATE clauses between them:

new IClause[] { MERGE.node(user).label("User").property("_id").value(...), SEPARATE.nextClause(), MERGE.node(team).label("Team").property("_id").value(...), SEPARATE.nextClause(), MERGE.node(user).relation(activeIn).out.... } ...

That works for all clauses which are concatenated and you don't want them to be concatenated.

Hope that helps, best regards, Wolfgang

Wolfgang-Schuetzelhofer commented 8 years ago

Hi Brian,

after having had a look into MERGE, it seems that multiple merge commands seperated by commas never work. I will change the code so that consecutive MERGE clauses will never be concatenated. The code change will also be in release 3.3.1.

best regards, Wolfgang

Wolfgang-Schuetzelhofer commented 8 years ago

Hi Brian,

JCypher 3.3.1 has been released, containing the previously mentioned fixes.

Best regards, Wolfgang

bconneen commented 8 years ago

Wolfgang,

Thank you once again for rapid response and resolution.