1
votes

Here is what I want to do: Connect users to the videos they watch like user -> video in a social graph or network type of graph.

How I did it:

LOAD CSV WITH HEADERS FROM 'asdfjkl;' AS line
CREATE (u {user: line.user }) - [:VIEW] -> (v {video: line.video})
RETURN u, v

The CSV file has 2 columns with headers user and video. Under user is a number identifying each user and under video is a number identifying each video. One user to one video. Sometimes the users name comes up again in the list to a different video. And sometimes the videos number comes up again because it is watched by a different user.

However, this returns relationships users viewing 1 video in each relationship. Thus, there are multiple nodes for each user and video.

What I want to do: Create more of a network or graph database to see what all users are viewing what videos and what all videos are watched by what users. To do this, the users and videos cannot be joined in single one to one relationships like how they are now.

How can I do this? Thank you in advance!

2
Use Labels :User and :Video !!Michael Hunger

2 Answers

1
votes

Adding to Luannes answer.

You need to use Labels and provide constraints!

LOAD CSV WITH HEADERS FROM 'asdfjkl;' AS line
MERGE (u:User {user: line.user })
MERGE (v:Video {video: line.video})
MERGE (u)-[:VIEW]->(v) 
RETURN u, v

You need to create a constraint on :User(user) and :Video(video)` for it to work correctly.

If you are importing larger volumes of data (> 100k rows) also use PERIODIC COMMIT Also the query above has to pull in your data eagerly to achieve separation.

Rather split it up into three queries:

CREATE CONSTRAINT ON (u:User) ASSERT u.user IS UNIQUE;
CREATE CONSTRAINT ON (v:Video) ASSERT v.video IS UNIQUE;

USING PERIODIC COMMIT 100000
LOAD CSV WITH HEADERS FROM 'asdfjkl;' AS line
WITH distinct line.user as user_data
MERGE (:User {user: user_data });

USING PERIODIC COMMIT 100000
LOAD CSV WITH HEADERS FROM 'asdfjkl;' AS line
WITH distinct line.video as video_data
MERGE (:Video {video: video_data });

USING PERIODIC COMMIT 100000
LOAD CSV WITH HEADERS FROM 'asdfjkl;' AS line
MATCH (u:User {user: line.user })
MATCH (v:Video {video: line.video})
MERGE (u)-[:VIEW]->(v);

Make sure to use the latest version (Neo4j 2.2.2).

1
votes

MERGE will make sure that it either creates the nodes/relationships if missing, or use them. Since line.user and line.video appear to be the equivalent of primary keys, this should work well

LOAD CSV WITH HEADERS FROM 'asdfjkl;' AS line
MERGE (u {user: line.user })
MERGE (v {video: line.video})
MERGE (u)-[:VIEW]->(v) 
RETURN u, v

More on MERGE: http://neo4j.com/docs/2.2.2/query-merge.html