Help on Movie/Television Social Network

18 views
Skip to first unread message

Vinicius Tavares

unread,
Aug 31, 2015, 1:03:48 AM8/31/15
to Neo4j
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.
  • 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

Max De Marzi Jr.

unread,
Aug 31, 2015, 7:31:57 PM8/31/15
to Neo4j
No, I hate this way of doing it.

Do this instead:

CREATE (me)-[r:has_story_2015_09_01]->(latest_story)

Then when you want the latest stories you can just query by the type and date.
if you want a 2 days, you can use the "|" operator as an OR :

MATCH (me)-[:HAS_STORY_2015_09_01|HAS_STORY_2015_09_02]->(story)
RETURN story
ORDER BY story.published_date DESC

This way you are not deleting relationships all over the place which makes a mess of data store.
You are using the relationship type as a sort of index. 
Reply all
Reply to author
Forward
0 new messages