Reputation: 23
I'm trying to migrate our current data set to Neo4J
and was fairly successful so far until I reach this problem. I'm trying to create a set of relationships between 2 node where the name of the relationship is a variable. In my MySQL database, I have Role object which map to a pair of (Resource, Action) so I'm trying to convert it to Neo4J
with data model such as (Role)-[Action]->(Resource)
. This is what I have but this doesn't seem like valid syntax:
USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM "file:///roletoresourceaction.csv" AS row
MATCH (role:Role {roleId: row.ROLE_ID})
MATCH (resource:Resource {resourceId: row.RESOURCE_ID})
MATCH (action:Action {actionId: row.ACTION_ID})
MERGE (role)-[r:action.name]->(roleAsResource)
Would appreciate any help on this. Thanks.
Upvotes: 1
Views: 1787
Reputation: 66989
Neo4j 3.x added support for apoc procedures (which must be installed on the server before they can be used).
With the apoc procedure apoc.create.relationship
, you should be able to do the equivalent of a MERGE
of dynamic relationship types. The Cypher language, by itself, only supports the creation/merging of static relationship types.
Hopefully, this works for you:
USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM "file:///roletoresourceaction.csv" AS row
MATCH
(role:Role {roleId: row.ROLE_ID}),
(resource:Resource {resourceId: row.RESOURCE_ID}),
(action:Action {actionId: row.ACTION_ID})
OPTIONAL MATCH (role)-[rel]->(resource)
WITH role, resource, action, COLLECT(TYPE(rel)) AS relTypes
WHERE NOT action.name IN relTypes
CALL apoc.create.relationship(role, action.name, NULL, resource) YIELD newRel
RETURN role, resource, newRel;
The OPTIONAL MATCH
and WHERE
clauses verify that the relationship does not already exist before allowing apoc.create.relationship
to create it.
ASIDE: I was also hoping to use the apoc.path.expand
procedure instead of the OPTIONAL MATCH
clause (with some additional changes), but that procedure currently seems to abort the query when it fails to find a match -- even testing the returned path for NULL
does not help.
Upvotes: 1
Reputation: 23
This solution worked for me
LOAD CSV WITH HEADERS FROM "file:///roletoresourceaction.csv" AS row
MATCH
(role:Role {roleId: row.ROLE_ID}),
(resource:Resource {resourceId: row.RESOURCE_ID}),
(action:Action {actionId: row.ACTION_ID})
OPTIONAL MATCH (role)-[rel]->(resource)
WITH role, resource, action, COLLECT(TYPE(rel)) AS relTypes
WHERE NOT action.name IN relTypes
CALL apoc.create.relationship(role, action.name, NULL, resource) YIELD rel
RETURN role, resource, rel;
Upvotes: 0