Question

I am learning about nosql database and neo4j. I want to know when should I define the relationship in nodes or in links?

For example:

(teacher)-[:TEACHS]->(student)

or

(Person)-[:TEACHS]->(Person)

I know it is not a good example for my question. But I think it must be an important topic in Neo4j or graph theory, but I could not find examples or discussion on the topic...

Was it helpful?

Solution

The best starting point is to consider the queries that you need to run. Use these to guide the way you represent the domain, rather than treating it as an abstract modelling problem.

For example you may decide that the most important query is: "given the name of a teacher, how many pupils do they have?"

MATCH ({name: "Bob"})-[:TEACHES]->(p) RETURN count(p)

This is the simplest way to express this query, so there is no need to complicate the model with node labels.

But then you may find that you need to get a list of all the teachers, at which point you could introduce a label.

MATCH (t:Teacher) RETURN t.name

Or you may even find that for performance reasons you need a label for the first query.

MATCH (:Teacher {name: {"Bob"})-[:TEACHES]->(p) RETURN count(p)

But it's really worth trying to stop yourself from doing too much modelling up front and including things in the model that may not be necessary. You will find that this results in a much simpler and more flexible model.

This raises the question of how to modify the data as the model changes. You will usually find that there is a series of safe, simple refactorings that you can do as you go along, just as though you were refactoring code. In this case you need to add labels to all nodes where a :TEACHES relationship starts.

MATCH (t)-[:TEACHES]->() SET t:Teacher

OTHER TIPS

I would say it depends a bit on your domain. Both

(teacher:Person:Teacher)-[:TEACHES]->(student:Person:Student)

Defines three labels - Person, Teacher and Student. This helps in defining traversals. However, if you want to prune traversals even on the relationship level, you can also do

(teacher:Person)-[:TEACHERS_TEACHES_STUDENT]->(student:Person)

Thus implicating the types of the nodes. While Relationship types are nice to use for semantic- and traversal reasons, there are not infinite amounts of them, and traversing them with Regexp etc is not great. So, don't encode relationship values into relationship types like dates or so (e.g. [:TEACHED_FROM_2013_to_2014])

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top