Hello everyone! As I've read on Michael's pinned post, we can try to solve modelling issues here on this group.
Here it goes:
I'm trying to make a small Movies/TV Shows Social Network.
The domain (simplified to focus on the problem):
A Profile can follow other Profiles and also Movies and TV Shows.
Profiles can create Images and Articles and maybe mention Movies and TV Shows on them.
A Profile has a News Feed containing all Media and Articles that:
- A Profile that he follows has created.
- A Movie or TV Show he follows has been mentioned in.
I had the idea that every media created (movie, article, image, video....) is part of a Profile's Story.
So, when I post a new image mentioning an Interest (Movie, TVShow), I also create a Story linking them, as such:
(Profile)-[has_story]->(Story)
(Interest)->[has_mention]->(Story) // optional
(Story)->[targets]->(Media)
Stories will also be a linked list for both Profile and Mentioned Movies, for query speed purposes. So:
(Movie)-[latest_mention]->(story)-[next]->(story2)-[next]->(story3)
(Profile)-[latest_story]->(story)-[next]->(story2)-[next]->(story3)
However, I'm struggling to UNION these two conditions. My current cypher is:
START me=node(0)
MATCH (me)-[:follows]->(interest)-[:latest_mention*0..1]->(story:Story)<-[:has_story]-(publisher:Profile)
MATCH (story)-[:targets]->(media)
RETURN story, media, interest, publisher
UNION
MATCH (me)-[:follows]->(publisher:Profile)-[:latest_story*0..1]->(story:Story)
MATCH (story)-[:targets]->(media)
OPTIONAL MATCH (story)<-[:has_mention]-(interest)
RETURN story, media, interest, publisher
ORDER BY story.created_time DESC
LIMIT 15
Is it a good approach? My write query seems to be quite ugly:
START me=node({ me }), interest=node({ interest })
OPTIONAL MATCH (me)-[r:latest_story]-(secondlateststory)
DELETE r
CREATE (me)-[:latest_status]->(latest_story:Story { story_payload })
CREATE (me)-[:has_story]->(latest_story)
WITH latest_story, collect(secondlateststory) AS seconds, interest
FOREACH (x IN seconds | CREATE (latest_story)-[:next]->(x))
WITH interest, latest_story
OPTIONAL MATCH (interest)-[r1:latest_mention]-(secondlatestmention)
DELETE r1
CREATE (interest)-[:latest_mention]->(latest_story)
CREATE (interest)-[:has_mention]->(latest_story)
WITH latest_story, collect(secondlatestmention) AS seconds
FOREACH (x IN seconds | CREATE (latest_story)-[:next]->(x))
RETURN latest_story as new_story
This query is adapted from the neo4j's cookbook about newsfeeds, merging with my need of mentions.
Am I doing it right? Is there a shorter or more performant path to do so?
Thank you for your help,
VInicius