Create a relationship between two already existing nodes by one common property

Hello guys!

I'm fairly new to neo4j and to cypher in general. Besides that, I'm not really good at using cypher. However, I want to create relationships between the nodes, that already exist in my database and share one property. So to give a specific example: I'd like to create a relationship between a letter and its sender. The common ground is the label of the person and the property sender of the letter. I just don't know how to narrow down my query, although I get why this ends up being a cartesian product.

Match (p:Person), (l:letter)
WHERE p.label = l.sender
CREATE (p)-[s:HAS_SENDED]->(l)
RETURN p,s,l

Could somebody please help me out here?
Probably it would best to use MERGE since the nodes themselves already exist in my database. Likely it's not just that easy to access the properties. Do I need to mention them first?
Thank you for your support and patience with this confused brain of mine!

Hello @lauri and welcome to the Neo4j community :slight_smile:

You are close and yes MERGE must be used in your case.
Are label and sender properties?

MATCH (p:Person)
MATCH (l:letter)
WHERE p.label = l.sender
MERGE (p)-[:HAS_SENDED]->(l)
RETURN *

Regards,
Cobra

Hello @cobra,

After all, I am not completely wrong :D Thank you for your quick reply!! For me that's already a success! :smiley:
So, yes, label and sender are in each case properties; so label is one of the persons properties and sender one of the letters.

This query will create a relation for each couple respecting the condition so depending of the size of your database, you may have to use the apoc.periodic.iterate() function.

Hi Cobra,

I have a similar problem. I have nodes for 'incident' and nodes for 'outcomes', I created an index on a property type 'crime_id' on both the incidents and outcomes. I now need to link the incident node and outcome node. Both share crime_id and so would need to link the corresponding incident node to outcome node.

I've tried

MATCH (i:Incident)
MATCH (o:Outcomes)
WHERE i.crime_id = o.crime_id
MERGE (i)-[:OUTCOME_HISTORY]->(o)
RETURN *

This doesn't seem to be working for me as it takes a very long time (over 3 hours) and still hasnt formed the relationship.

Any advice would be appreciated.

Thanks,

Sam

Hello @samvarughese8 and welcome to the Neo4j community :slight_smile:

Did you create a index or a unique constraint? Did you create a unique constraint on both nodes?
You can use APOC and the apoc.periodic.iterate() function:

CALL apoc.periodic.iterate("
    MATCH (i:Incident) 
    MATCH (o:Outcomes) 
    WHERE i.crime_id = o.crime_id
    RETURN i, o
    ", "
    MERGE (i)-[:OUTCOME_HISTORY]->(o)
    ", {batchSize: 10000, parallel: true}
)

Regards,
Cobra

I created an index on the crime_id type. I found the solution, when reversing line 3 to give:

WHERE o.crime_id = i.crime_id

It seems to work and has created the relationships.