Reputation: 1160
I'm working with prepared statements via the Neo4J JDBC driver, and have a need to create node and relationship labels whose names are driven by the data we will be receiving.
For example, I'd like to create a prepared statement along these lines:
MERGE (test:{1} {id: {2}) ON CREATE SET test.id = {2}
OR
MERGE (test:Test)-[:{1}]->(test2:Test)
These don't currently work, as it seems Neo4J doesn't interpret the placeholder {1}
as a placeholder, instead seeing it as an invalid label name.
Another possibility I'm exploring is that we may be able to extend Cypher via a stored procedure, though I suspect we may run into the same limitation.
Hoping someone can provide some insight as to whether there is any way to accomplish this with Cypher.
Thanks!
UPDATE:
An answer below suggests using APOC's apoc.create.node
procedure, but what I need is to merge on a dynamic label. Updated the title to reflect this.
Upvotes: 3
Views: 519
Reputation: 1334
After trying almost half a day, I finally find out this method:
UNWIND {batch} as row
MERGE (n { id: row.id }) SET n += row.properties
WITH n
CALL apoc.create.addLabels(id(n), [n.label]) YIELD node
RETURN node
and the performance is almost the same as purely MERGE.
Many thanks for this refer: SET label : pass label name as parameter
Upvotes: 0
Reputation: 1160
I ended up using a different procedure from APOC - apoc.cypher.doIt
, as it turns out APOC doesn't have a way to merge with dynamic labels as of yet. See feature request: https://github.com/neo4j-contrib/neo4j-apoc-procedures/issues/271
Below is what I ended up doing. Note that the requirement was to iterate (in this case using UNWIND) over a collection and merge nodes with dynamic labels pulled from this collection, and then merge a relationship between a pre-existing node and this new node:
WITH myNode, myList
UNWIND categories AS catArray
WITH myNode, 'MERGE (cat:' + catArray[0] + ' {value: "' + catArray[1] + '" }) ON CREATE SET cat.value = \"' + catArray[1] + '\" RETURN cat' AS cypher
CALL apoc.cypher.doIt(cypher, {}) YIELD value
WITH myNode, value.cat as cat
MERGE (myNode)-[:IN_CATEGORY]->(cat)
Upvotes: 2
Reputation: 11216
You can use APOC to create dynamic relationships. Similar APOC procedures exist for creating nodes with dynamic labels or adding dynamic labels to nodes.
MERGE (test:Test {name: 'Test'})
WITH test
MERGE (test2:Test {name: 'Test 2'})
WITH test, test2
CALL apoc.create.relationship(test, {new_rel_type}, {}, test2) YIELD rel
RETURN test, test2, rel
Upvotes: 1