Aggregate/collapse/roll-up relationships with Cypher

I have a graph representing the pub/sub messaging configuration details in our micro-service landscape.
For some use-cases, it makes more sense to have aggregated/collapse/rolled-up relationship between publishers and subscribers, hiding away various details.

The base graph model is as follows:
(publisher:Service )-[:PUBLISH]->(:Topic {name})<-[:TOPIC]-(:Subscription)-[:QUEUE]->(:Queue)<-[:OWNER]-(subscriber:Service)
In words:

  • a publisher publishes to a topic
  • a subscriber owns a queue, which will receive messages due to a subscription on a topic

Based on this graph model, I would like to create a new additional 'collapsed' or 'rolled-up' relationship called PUBSUP

  • for each unique publisher-subscriber pair
  • with a 'topics' property, holding a list of topics this publish-subscriber pair share

The resulting graph model would look like this: (publisher:Service )-[:PUBSUB {topics}]->(subscriber:Service)

Being more accustomed to procedural languages like Java as opposed to query languages like Cypher, my first intuition is to program this - in Java - in a procedural style. And that will probably work.

However, I'm curious to learn how I could benefit from the expressiveness of Cypher to facilitate these requirements.
Any pointers to Cypher language elements that could help me out here are very much appreciated.


That's as simple as

MATCH (publisher:Service )-[:PUBLISH]->(t:Topic)<-[:TOPIC]-(:Subscription)-[:QUEUE]->(:Queue)<-[:OWNER]-(subscriber:Service)
MERGE (publisher)-[ps:PUBSUB]->(subscriber) 
ON CREATE SET ps.topics = [] 
ON MATCH SET ps.topics = ps.topics + 

The MERGE avoids duplicated relationships between the same publisher and subscriber.

Thnx for the quick response Stefan.

This looks like a very elegant solution. I'm going to try it this afternoon.