cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Replace relationship Or switch relationship

12kunal34
Graph Fellow

Hello Everyone,

I need some help in a scenario related to relationship.
For E.g. currently i am having a relationship between two nodes A and B like below.
A-[rel]->B

now it may be possible that in future it get changed . for all properties and data for relationhsip rel need to switch a node C
now relationship is
A-[rel]->C

how i can do that ?
rel can not be duplicate . if 2nd scenario comes then scenario 1 should be removed.

7 REPLIES 7

ameyasoft
Graph Maven

Hi,

I would like to follow the versioning approach for keeping the data for historical purposes. Here is my approach for your scenario.

Here I add a 'active' property to the relationship and set that to 'yes':
with
CREATE (h:hospital {name:"xyz"})
CREATE (n:owner {name:"abc"})
CREATE (h)-[:OWNER {active:"yes"}]->(n)
RETURN h,n;
2X_8_8f6f50c2e41ee03f6cea8098191fb3b94d4a4f2d.png

Create a new owner node and connect it to hospital node setting the OWNER property to 'yes' . Prior to this set the OWNER property to 'no'.

Cypher query:

MATCH (c:hospital)-[r:OWNER]->(d:owner)
WHERE c.name="xyz" AND d.name = "abc"
SET r.active = "no"
CREATE (f:owner {name:"cde"})
CREATE (c)-[:OWNER {active:"yes"}]->(f)
RETURN c, d, f;
2X_6_68c59e07248734b61237abcd212c2ea451e75a66.png

After this you can delete the old owner node with appropriate queries.
Remember to query on [:OWNER {active:"yes"}] relationship.

-Kamal

There is an APOC Procedure for this, refactoring a relationship which will do the whole create-new-then-delete-old relationship process for you.

...
// assume a, b, c, and rel are already in scope
CALL apoc.refactor.to(rel, c) YIELD input, output, error
RETURN input, output, error

12kunal34
Graph Fellow

Thanks @ameyasoft and @andrew.bowman

i am refactoring relationship with data using batch import.
will it work in this case ??

Hi Andrew,

Looks like refactoring relationship works strictly for only two nodes: (a)-[:]->(b).
When applied this to (a)-[:]->(b)-[:]-(d).... scenario it deleted all the nodes past (b).

Before:
2X_5_5d83e66b9cb4a72a5f4dd33e282e22984a188c67.png

After:
2X_2_274c1b9645e48505a3d8fa8035551ce0703ed835.png

Recently I learnt this hard way (losing data). No mention of this in APOC user guide.
-Kamal

@ameyasoft I'm not quite following what you attempted here, and to my knowledge nodes would not be deleted by a relationship refactoring call.

Please provide more information, preferably cypher to create the smallest example graph needed and the queries used to reproduce this outcome.

Hi,

Redirecting [:ZIPCODE] relationship to (d:Zip2 {id:2135}) from (d:Zip2 {id:1234})

Query 1:
CREATE (c:County {name:"xyz"})-[r:ZIPCODE]->(h:Zip {id:1234})-[:PLACE]->(e:Place {name:"abc"})-[:TYPE]->(k:Type {name:"cv"})
CREATE (d:Zip2 {id:2135})
RETURN *;
2X_8_89615392c91da1d650aa00f8a03148b16a37d16a.png

MATCH (c:County {name:"xyz"})-[r:ZIPCODE]->(h:Zip {id:1234})-[:PLACE]->(e:Place {name:"abc"})-[:TYPE]->(k:Type {name:"cv"})
MATCH (d:Zip {id:2135}) WITH d, c, r
CALL apoc.refactor.to(r, d) YIELD input, output, error
RETURN *;
2X_6_618c54ffaede83a3a5fa37e30c1feb8401bd74b1.png

Looking at this I thought I lost other nodes. After spending some time I tried MATCH(n) RETURN n and this is what I found:
2X_7_709547b4f375791bbab175d67a94a87a53b7da45.png

This broke one path into two paths. Luckily it was a test database. To connect these two broken paths used apoc.refactor.mergeNodes([node1,node2])

Query 2:
MATCH (d:Zip {id:2135}), (a:Zip {id:1234})
CALL apoc.refactor.mergeNodes([d,a], {properties:"discard"})
YIELD node RETURN node;
2X_2_29da26050639c18b387e7fe1ee29c94205cb24bc.png

Above result could easily be obtained with Query 1 and Qurery 2 without redirecting relationship. This shows that refactoring relationship works strictly for only two nodes: (a)-[:]->;(b).

These are my findings.

-Kamal

Hi Kamal,

This actually looks like correct behavior.

Your original relationship was from the :Country node to the :Zip node with id 1234.

Your call redirected the relationship (deleted the old and created a new relationship) from the :Country node to the :Zip2 node with id 2135. The relationships previously in place (from the :Zip with id 1234 to the :Place node, and the relationship from the :Place node to the :Type node) were not changed in any way, nor were any nodes deleted.

To make sure it's clear, the refactor call is only used to redirect a single relationship from (or to) one node to another, it does not refactor an entire path.

I'm not entirely clear on what outcome were you were expecting to see and how you thought the refactor call was meant to work, but if you open up a separate question with what kind of thing you are attempting to do I may be able to help you with such a query.