0
votes

Model

I have Cinemas, Films and Users and I want to model View relationships as first class citizens of the graph, for example: "Me went to cinema #58 to see film #43483", in the future I may want add "on 24th May 2013" or "with friend1 and friend2" to the View "relationship", example:

CREATE
(u1:User {id:1}),
(u2:User {id:2}),
(f1:Film {id:1}),
(f2:Film {id:2}),
(c1:Cinema {id:1}),
(c2:Cinema {id:2}),
// (v:View), (u1)-[:ATTENDED]->(v),(c1)<-[:AT]-(v),(v)-[:WATCHED]->(f1)

I've been trying to figure out how to create a unique View (i.e. a person cannot see the same film in the same cinema twice [here's where the extra date relationship will come in]) with a query that if run twice no duplicate View node is created.

Using CREATE UNIQUE take 1

MATCH (c:Cinema {id:1}), (f:Film {id:1}), (u:User {id:1})
CREATE UNIQUE (v:View),
    (u)-[:ATTENDED]->(v),
    (c)<-[:AT]-(v),
    (v)-[:WATCHED]->(f)
return v, u, c, f

http://console.neo4j.org/r/xcu90c Creating unique nodes AND relationships seems unsupported.

Using CREATE UNIQUE take 2

If I remove the separate node creation, it kind of works, until I don't create a second View: http://console.neo4j.org/r/x15bk1

Using MERGE

MATCH (c:Cinema {id:1}), (f:Film {id:1}), (u:User {id:1})
MERGE (u)-[:ATTENDED]->(v:View), (c)<-[:AT]-(v), (v)-[:WATCHED]->(f)
return v, u, c, f

Documentation says you can create a path with MERGE, but seemingly only straight paths... the above gives a syntax error on comma.

So essentially I don't want a node to be unique (View doesn't have any properties), I want to make the relationships of the node unique. Please suggest a solution.

Losing hope

My ideas of possible workarounds are (if all else fails):

  • duplicate the cinemaID, filmID and userID on the View node and put a unique constraint on that
  • Ignore atomicity and just query, check and create the nodes/relationships in separate queries

So far I'm not impressed with neo4j, so many things don't work which should.

2
Based on the answers - leading to the same results - may I have something wrong with the structural design/idea...?TWiStErRob

2 Answers

0
votes

I think it's barfing on the lonely (v:View) piece of your pattern in take 1. Try this one:

MATCH (c:Cinema { id:58 }),(f:Film { id:43483 }),(u:User { name:"twister" }) 
CREATE UNIQUE (u)-[:ATTENDED]->(v:View),(c)<-[:AT]-(v:View),(v:View)-[:WATCHED]->(f) 
RETURN v, u, c, f
0
votes

Can you try with multiple MERGE statements, works for me:

MATCH (c:Cinema {id:1}), (f:Film {id:1}), (u:User {id:1})
MERGE (u)-[:ATTENDED]->(v:View)
MERGE (c)<-[:AT]-(v)
MERGE (v)-[:WATCHED]->(f)
RETURN v, u, c, f