cancel
Showing results for 
Search instead for 
Did you mean: 

Join the community at Nodes 2022, our free virtual event on November 16 - 17.

How to "replace" relationships while importing

#cypher #relationship #load

Hi,

I'm loading some data where apoc.load.jsonParams gives me a data object that has a number of "issues". I can UNWIND those issues and create a Node for each of them.

Every Issue also has a Status. So while creating a specific "Issue" Node, I'm also creating a "Status" node and creating a relationship between them:

call apoc.load.jsonParams(url, {Authorization: $auth}, null) yield value
unwind value.issues as issue
merge (item:JiraItem {jiraId: issue.id})
set item.self = issue.self
set item.name = issue.key
set item.summary = issue.fields.summary

merge (status:JiraStatus {jiraId: issue.fields.status.id})
set status.self = issue.fields.status.self
set status.name = issue.fields.status.name
merge (item)-[:HAS]->(status)

The problem is: the Status may change. So the next time I load the same "Issue", which will Update the "Issue" Node, it will create another Relationship to another "Status" Node, so now the "Issue" Node has two Statuses, where it's supposed to only have the new one.

How would I solve this problem? I cannot use:

call apoc.load.jsonParams(url, {Authorization: $auth}, null) yield value
unwind value.issues as issue
merge (item:JiraItem {jiraId: issue.id})
set item.self = issue.self
set item.name = issue.key
set item.summary = issue.fields.summary

match (item)-[r:HAS]-(:JiraStatus)
delete r
merge (status:JiraStatus {jiraId: issue.fields.status.id})
set status.self = issue.fields.status.self
set status.name = issue.fields.status.name
merge (item)-[:HAS]->(status)

because I cannot use a MATCH without a WITH. But I'm not sure a new "subquery" (which would happened with the WITH) makes sense either.

Question: What is the best way to "update relationships" when importing?

Thanks

1 REPLY 1

Cobra
Ninja
Ninja

Hello @guillaume.hanique and welcome to the Neo4j community

This query should do what you asked:

CALL apoc.load.jsonParams(url, {Authorization: $auth}, null) 
YIELD value 
UNWIND value.issues AS issue 
MERGE (item:JiraItem {jiraId: issue.id}) 
SET 
    item.self = issue.self, 
    item.name = issue.key, 
    item.summary = issue.fields.summary 
WITH item
OPTIONAL MATCH p=(item)-[:HAS]-(:JiraStatus)
FOREACH (rel IN relationships(p) | REMOVE rel)
WITH item
MERGE (status:JiraStatus {jiraId: issue.fields.status.id})
SET 
    status.self = issue.fields.status.self, 
    status.name = issue.fields.status.name 
MERGE (item)-[:HAS]->(status)

Regards,
Cobra