Neo4j cypher query fails with unknown syntax error

2019-08-26 21:43发布

问题:

I have the following paramObj and dbQuery

 paramObj = {
                    email:         newUser.email, 
                    mobilenumber:  newUser.telephone,
                    password:      newUser.password,
                    category:      newUser.category,
                    name:          newUser.name,
                    confirmuid:    verificationHash,
                    confirmexpire: expiryDate.valueOf(),
                    rewardPoints:       0, 
                    emailconfirmed:    'false',
                    paramVehicles:      makeVehicleArray,  
                    paramVehicleProps:  vehiclePropsArray
                     }
dbQuery = `CREATE (user:Person:Owner {email:$email})                                    
           SET  user += apoc.map.clean(paramObj, 
                 ['email','paramVehicles','paramVehiclesProps'],[])
           WITH user, $paramVehicles AS vehicles
            UNWIND vehicles AS vehicle
            MATCH(v:Vehicles {name:vehicle}) 
            CREATE UNIQUE (user)-[r:OWNS {since: timestamp()}]->(v)
            RETURN user,r,v`;

Then I tried to execute

 commons.session
              .run(dbQuery, paramObj)
              .then(newUser => {
                  commons.session.close();
                  if (!newUser.records[0]) {........

I am getting

Error:  {"code":"Neo.ClientError.Statement.SyntaxError","name":"Neo4jError"}

which doesn't direct me anywhere. Can anyone tell me what am I doing wrong here?

This is actually the first time I am using the query format .run(dbQuery, paramObj) but this format is critical to my use case. I am using Neo4j 3.4.5 community with apoc plugin installed.

Ok...so I followed @inversFalcon suggestion to test in browser and came up with following parameters and query that closely match the ones above:

   :params paramObj:[{ email:"xyz123@abc.com", mobilenumber:"8711231234",password:"password1", category:"Owner",name:"Michaell",vehicles:["Toyota","BMW","Nissan"],vehicleProps: [] }]

and query

PROFILE
CREATE (user:Person:Owner {email:$email})
SET  user += apoc.map.clean($paramObj, ["email","vehicles","vehicleProps"],[])
WITH user, $vehicles AS vehicles
UNWIND vehicles AS vehicle
MATCH(v:Vehicles {name:vehicle})
MERGE (user)-[r:OWNS {since: timestamp()}]->(v)
RETURN user,r,v;

Now I get Neo.ClientError.Statement.TypeError: Can't coerce `List{Map{name -> String("Michaell"), vehicles -> List{String("Toyota"), String("BMW"), String("Nissan")},.......

I also reverted to neo4j 3.2 (re: an earlier post by Mark Needham) and got the same error.

回答1:

You should try doing an EXPLAIN of the query using the browser to troubleshoot it.

A few of the things I'm seeing here:

You're referring to paramObj, but it's not a parameter (rather, it's the map of parameters you're passing in, but it itself is not a parameter you can reference in the query). If you need to reference the entire set of parameters being passed in, then you need to use nested maps, and have paramObj be a key in the map that you pass as the parameter map (and when you do use it in the query, you'll need to use $paramObj)

CREATE UNIQUE is deprecated, you should use MERGE instead, though be aware that it does behave in a different manner (see the MERGE documentation as well as our knowledge base article explaining some of the easy-to-miss details of how MERGE works).



回答2:

I am not sure what caused the coercion error to disappear but it did with the same query and I got a "expected parameter error" this was fixed by using $paramObj.email, etc. so the final query looks like this:

CREATE (user:Person:Owner {email: $paramObj.email})
SET  user += apoc.map.clean($queryObj, ["email","vehicles","vehicleProps"],[])
WITH user, $paramObj.vehicles AS vehicles
UNWIND vehicles AS vehicle
MATCH(v:Vehicles {name:vehicle})
MERGE (user)-[r:OWNS {since: timestamp()}]->(v)
RETURN user,r,v;

which fixed my original problem of how to remove properties from a map when using SET += map.



标签: neo4j cypher