DELETE all relationships before creating new ones

We want to store a simple graph: (p:Person {id: 5)-[:LIKES]->(s:Song)

When we receive new information about the songs that a person likes, we want to

  • first delete existing LIKE-relationships for this person
  • create the new ones

The last part is easy:

foreach (song in $k.songdata |
    create (p)-[:LIKES]->(s:Song {title: k.title}))

For the first part we could use sth like

match (p:Person {id: k.id})-[:LIKES]->(s) detach delete (s)

But how can we combine these in one statement? We need to do this with plain Cypher, without apoc.

Hello @FrankR85 :slight_smile:

First, be aware it's a good thing to separate these queries, but here you have a way (moreover UNION should not be used like this):

MATCH (p:Person {id: k.id})-[r:LIKES]->(s)
DELETE (r)
UNION
FOREACH (song IN $k.songdata |
    CREATE (p)-[:LIKES]->(s:Song {title: k.title}))

You could also have a look at MERGE.

Regards,
Cobra

Thank you for your reply!
We would split the statement if we could, but we are using Neo4j streams and we noticed a massive degrade in throughput when we used apoc.cypher.runMany. It is up to 10x slower than a plain Cypher query.

That being said, I have some trouble getting your query to work within UNWIND.
Running

UNWIND $events as event
MATCH (p:Person {id: event.id})-[r:LIKES]->(s)
DELETE (r)
UNION
FOREACH (song IN event.songdata |
    CREATE (p)-[:LIKES]->(s:Song {title: k.title}))

yields an error because event is unknown in the clause following the union. I just can't get it to work. :see_no_evil:

If you know of another possibility to split the statements, we would be glad to hear it.

Unfortunatly we haven't figured out yet the exact reason why apoc.cypher.runMany is so slow.

Do you use a driver to send queries to your database?

UNWIND $events as event
MATCH (p:Person {id: event.id})-[r:LIKES]->(s)
DELETE (r)
UNION
UNWIND $events as event
FOREACH (song IN event.songdata |
    CREATE (p)-[:LIKES]->(s:Song {title: k.title}))

Thank you! This query works fine! :sunglasses:

I don't know what you mean with the question about the driver. We use a Cypher-Template as Neo4j streams sink ingestion strategy.

Nice:)

I was talking about this: