Search code examples
neo4jcypherneo4j-apoc

Cypher dynamic relationship with conditional APOC procedure?


I am learning cypher and trying to find out a way to create dynamic relationship when a condition passes. Here is an example:

we have single node:

(n2)

and another node which has unknown relationship of TEMP_1 or TEMP_2 with its child:

(n1)------[TEMP_1 or TEMP_2]------>(child)

we want to create relationship between (n2) and (child) if it exists

(n2)------[TEMP_1 or TEMP_2]------>(child)

Here is query:

MATCH (n1: NODE_1)
MATCH (n2: NODE_2)
OPTIONAL MATCH (n1)-[rel:TEMP_1|TEMP_2]->(child)
CALL apoc.do.when(child IS NOT NULL, "CREATE (n2)-[:r]->(ch) RETURN TRUE", "", {n2:n2, r:type(rel), ch:child}) YIELD value

However this creates me relationship of type "r" instead of taking type from rel so it looks like following:

(n2)-[r]->(child)

Is there a way to create dynamic relationship on specific condition?

I have another idea but that would require carry on with query execution even if MATCH returns nothing.

MATCH (n1: NODE_1)
MATCH (n2: NODE_2)
MATCH (n1)-[rel:TEMP_1|TEMP_2]->(child)
CALL apoc.do.when(child IS NOT NULL, "CREATE (n2)-[:r]->(ch) RETURN TRUE", "", {n2:n2, r:type(rel), ch:child}) YIELD value
...[other parts of query e.g. MATCH | CREATE ...]

There is no OPTIONAL MATCH this time and when child IS NULL it returns and does not bother calling APOC procedure. However I would like to carry on with other part of the query e.g. create other relationships. Is there a way to accomplish something like that?


Solution

  • The apoc.create.relationship function can create a relationship with a dynamic type.

    Also, you need to use the "$" prefix when referencing a parameter.

    For example:

    OPTIONAL MATCH (n1: NODE_1)-[rel:TEMP_1|TEMP_2]->(child)
    CALL apoc.do.when(
      child IS NOT NULL,
      "MATCH (n2: NODE_2) CALL apoc.create.relationship(n2, $r, $ch) YIELD rel RETURN rel",
      "",
      {r:type(rel), ch:child}) YIELD value
    ...
    

    This snippet only gets n2 as needed, which assumes that you do not need n2 later in the query.