Search code examples
neo4jcyphergraph-databases

Is it possible to merge using data-driven node or relationship labels?


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.


Solution

  • 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)