Search code examples
variablesneo4jrelationship

variable relationships within a single query in neo4j


I am new to neo4j. I have two types of nodes in the database, i.e., "Person" and "House". I want to create relationships between each "Person" and the "House" with names like "resident_1", "resident_2", etc. Please find my code below:

CREATE (n1:Person {name: '1'})
CREATE (n2:Person {name: '2'})
CREATE (n3:Person {name: '3'})
CREATE (n4:Person {name: '4'})
CREATE (t1:House {name:"T1"})
With n1, n2,n3,n4,t1
MATCH(a:House{name: "T1"})
with a
MATCH(b:Person) 
WITH a, b
Create (a)-[r:resident_1]->(b)
RETURN type(r)

The output generates

╒════════════╕
│"type(r)"   │
╞════════════╡
│"resident_1"│
├────────────┤
│"resident_1"│
├────────────┤
│"resident_1"│
├────────────┤
│"resident_1"│
└────────────┘

But, I want to generate

╒════════════╕
│"type(r)"   │
╞════════════╡
│"resident_1"│
├────────────┤
│"resident_2"│
├────────────┤
│"resident_3"│
├────────────┤
│"resident_4"│
└────────────┘

How to do that? Any help is highly appreciated. Thanks!


Solution

  • Cypher only supports static value of relationship type so you need to use an APOC function (it is awesome) if the relationship type is dynamic. If you need help on installing APOC, here it is: https://neo4j.com/labs/apoc/4.1/installation/. You need to create a map of Person (resident) to the Relationship Type (resident_1) then we will use apoc.create.relationship:

    https://neo4j.com/labs/apoc/4.1/overview/apoc.create/apoc.create.relationship/

    // Let us collect all person and order by name
    MATCH (b:Person)
    WITH collect(b) as setB, count(b) as cnt ORDER BY b.name
    // create a map of person and relationship type (person1 -> resident_1)
    WITH [idx in RANGE(1, cnt)| {b: setB[idx-1], rela: 'resident_' + toString(idx)}] as relTypes
    // get the house node
    MATCH (a:House{name: "T1"})
    // relaTypes is a list so let us do UNWIND (this is like a for loop)
    UNWIND relTypes as relType
    // each relationship type is a dictionary so resident_1 is mapped to person1 and so on.  relType.rela is the relationship string that we want
    CALL apoc.create.relationship(a, relType.rela, NULL, relType.b) YIELD rel
    RETURN a.name as name, relType.b as person, relType.rela as relType
    

    Below is the result: enter image description here