Any ideas? Trying to create relationships between students, sessions, and subjects

Hello All,

I have a seemingly simple problem.

I have a set up the following nodes:

  • Students (121)
  • Subjects (8)
  • Sessions (5)

Each student has a preference for subjects that I have added as edge properties. The edges are as follows:

  • (Student)-[:HAS_PREFERENCE]->(Subject)
  • (Subject)-[:IN]->(Session)

Some relevant constraints:

  • Not all subjects are in each session.
  • A student can only be in a single session/subject combination. (i.e. a student will not take the same subject again if they already have taken that subject previously.

The kicker is I want to randomly assign the students to the session and subject.

Is there a way to do this within the constraints of Cypher?

Thanks for any help you can provide.



I just wanted to check something - would you be randomly assigning all the students to a subject/session? Or are the students already assigned to something?


1 Like


Thanks for getting back to me.

The assignment of the students is based on their subject preference (0-5) 5 being the highest value. If they have a preference >= 3 than they will get assigned to a session for that subject.


1 Like

Your model may need reworking, but for now you may capture what subject they've been assigned to by connecting them directly to session, and then going through that to see what session it is,


(:Student {name:'Joe'})-[:HAS_PREFERENCE {score:5}]->(:Subject {name:'Maths'})
(:Student {name:'Joe'})-[:ASSIGNED]->(:Session {name:'MATHS_1})

To find subjects which a student has a preference for but has done no sessions in, you could do something like this:

MATCH (s:Student)-[hp:HAS_PREFERENCE]->(sub:Subject)
WHERE hp.score>=3 AND NOT (sub)-[:HAS_SESSION]->(:Session)<-[:ASSIGNED]-(s) //we don't want any subjects/sessions the student has already taken

For the random component, you can do something like:

WITH s, sub
MATCH (sub)-[:HAS_SESSION]->(sess:Session) //fetch back all the available sessions
WITH s, sess, rand() as r ORDER BY r  LIMIT 1 //randomly pick a subject and a student (this only assigns 1 session to 1 student!)
CREATE (s)-[:ASSIGNED]->(sess)