Aggregate/collapse/roll-up relationships with Cypher

relationship

(Knieuwenhuys) #1

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.

Kristel


(Stefan Armbruster) #2

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 = [t.name] 
ON MATCH SET ps.topics = ps.topics + t.name 

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


(Knieuwenhuys) #3

Thnx for the quick response Stefan.

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