Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
01-14-2019 09:54 AM
What is the best way to run a multi-statement cypher query?
I would like to run a small cypher query without running transactions in Java etc, simply for partial backup/restore purposes.
As far as I understand this would be done using CSV or cypher. I've extensively tested this.
CSV:
CALL apoc.export.csv.query("MATCH (x:X)-[r:relationship]->(y:Y) RETURN x.x as xx, properties(r) as rr, y.y as yy", "x.csv", {})
Although it's possible to both export, and interpret property maps with APOC, it's not possible to dynamic assign property map (i.e. SET r = {...}); nodes/relationship properties can only be set with explicit labelled assignment, making this method inconvenient for our purpose.
Cypher should have more support, though as I understand export is again only possible using APOC e.g.:
call apoc.export.cypher.query("MATCH (x:X) RETURN *", "x.cypher", {format:'plain', cypherFormat:'updateStructure'})
How can a cypher be imported? I have tried the following:
Note contrary to documentation, runFile only works WITHOUT cypher wrapping (BEGIN / :begin etc), using format:'plain'.
Any advise appreciated.
Neo4J 3.5.1: Desktop / Linux
01-15-2019 05:49 AM
You can assign dynamic maps (or parameters) to nodes and relationships with
SET e = value
SET e += value
SET e += $param
SET e += apoc.map.fromXxx(...)
How many elements do your cypher statements have?
Can you show an example?
Is it one gigantic statement ? Or many smaller ones separated by semicolons ?
Yes that's what should be documented, that the formats
Unfortunately procedures cannot mix data and schema statements that's why there is a separate runFile
and runSchemaFile
01-15-2019 05:50 AM
What is your original goal?
01-15-2019 10:09 AM
Thank you for the response @michael.hunger
As mentioned my original purpose is to run a partial backup/restore (without the need to code an application around it). I'm not making any structural changes - just setting properties on (existing) relationships.
CSV:
I have tested this extensively, and found that SET e = [variable from parameter containing map] (e.g. SET r=apoc.convert.fromJsonMap(row.x)) always gives this error:
Neo.ClientError.Statement.TypeError: Property values can only be of primitive types or arrays thereof
I can provide this obfuscated load in line with the previous export:
LOAD CSV WITH HEADERS FROM "file:///x.csv" AS row MATCH (x:X {x:row.xx}), (y:Y {y:row.yy}) MERGE (x)-[r:relationship]->(y) SET r=apoc.convert.fromJsonMap(row.r)
It is worth mentioning that I have boolean properties, though surely this should not be a problem?
CYPHER:
You mention the 'cypher-shell' format is for cypher-shell, which seems intuitive, however how can this be loaded other than by query incorporating the runFile call (which actually requires the 'plain' format to work)?
I have not found any way of loading or running a cypher from file, please let me know if I missed something obvious.
01-15-2019 06:30 PM
cat cypher-shell-format-file.cypher | cpyher-shell -u neo4j -p <password> -a bolt://localhost
01-16-2019 03:45 AM
CSV:
Export:
CALL apoc.export.csv.query("MATCH (x:X)-[r:relationship]->(y:Y) RETURN ID(x) as x,r,ID(y) as y", "test.csv", {})
File (note forum converts [ and ] to 😞
"x","r","y"
"1919374","{""id"":3919461,""type"":""relationship"",""start"":1919374,""end"":1919375,""properties"":{""myProperty"":{""offset"":{""totalSeconds"":0,""id"":""Z"",""rules"":{""transitions"":,""transitionRules"":,""fixedOffset"":true}},""zone"":{""totalSeconds"":0,""id"":""Z"",""rules"":{""transitions"":,""transitionRules"":,""fixedOffset"":true}},""dayOfYear"":1,""dayOfWeek"":""TUESDAY"",""month"":""JANUARY"",""dayOfMonth"":1,""year"":2019,""monthValue"":1,""hour"":0,""minute"":0,""nano"":0,""second"":0,""chronology"":{""id"":""ISO"",""calendarType"":""iso8601""}}}}","1919375"
Import:
LOAD CSV WITH HEADERS FROM "file:///test.csv" AS row MATCH (x:X) MATCH (y:Y) WHERE ID(x)=toInteger(row.x) AND ID(y)=toInteger(row.y) MERGE (x)-[r:relationship]->(y) SET r=apoc.convert.fromJsonMap(row.r).properties
Result:
Neo.ClientError.Statement.TypeError: Property values can only be of primitive types or arrays thereof
CYPHER:
Testing the described method unfortunately does not seem to add any relationships. Further investigation shows there appears to be an issue with the exported cypher syntax.
If the first row is (forum seems to eat the single quotes around UNIQUE IMPORT LABEL etc):
MATCH (n1:UNIQUE IMPORT LABEL
{UNIQUE IMPORT ID
:4762}), (n2:UNIQUE IMPORT LABEL
{UNIQUE IMPORT ID
:1919299}) MERGE (n1)-[r:relationship
]->(n2);
Then running this query should return existing nodes:
MATCH (n1:UNIQUE IMPORT LABEL
{UNIQUE IMPORT ID
:4762}), (n2:UNIQUE IMPORT LABEL
{UNIQUE IMPORT ID
:1919299}) return n1,n2
However, it does not find the nodes. Is this depricated use of ID? The following does return them:
MATCH (n1), (n2) where ID(n1)=4762 and ID(n2)=1919299 return n1,n2
PS: APOC version 3.5.0.1
01-16-2019 05:10 AM
There are two things that might not work out of the box:
01-16-2019 06:17 AM
I would also appreciate any recommendations on the issue with cypher export. Is this a deprecation bug?
01-16-2019 07:47 AM
date(year, month, day, timezone)
from that json data, see manual,What was the cypher export again, it would be good to raise one topic per question otherwise it gets all messed up.
01-16-2019 08:26 AM
Re CSV, understood.
Re Cypher - following your suggestion, please see Export a (sub)graph to Cypher script and import it again
All the sessions of the conference are now available online