在节点或链接中定义关系?

时间:2014-04-29 03:34:31

标签: graph neo4j spring-data-neo4j

我正在学习nosql数据库和neo4j。我想知道何时应该在节点或链接中定义关系?

例如:

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

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

我知道这不是我的问题的好例子。但我认为它必定是Neo4j或图论中的一个重要主题,但我找不到关于这个主题的例子或讨论......

2 个答案:

答案 0 :(得分:2)

我想说这取决于您的域名。两个

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

定义三个标签 - PersonTeacherStudent。这有助于定义遍历。但是,如果您想在关系级别修剪遍历,也可以执行

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

因此暗示了节点的类型。虽然关系类型很好地用于语义和遍历的原因,但它们并不是无限量的,并且使用Regexp等遍历它们并不是很好。因此,不要将关系值编码为关系类型,例如日期等(例如[:TEACHED_FROM_2013_to_2014]

答案 1 :(得分:2)

最好的出发点是考虑您需要运行的查询。使用这些来指导您表示域的方式,而不是将其视为抽象建模问题。

例如,您可以决定最重要的查询是:"给定教师的姓名,他们有多少学生?"

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

这是表达此查询的最简单方法,因此无需使用节点标签使模型复杂化。

但是你可能会发现你需要获得所有教师的名单,此时你可以引入一个标签。

MATCH (t:Teacher) RETURN t.name

或者您甚至可能会发现,出于性能原因,您需要为第一个查询添加标签。

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

但是,真的值得尝试阻止自己在前面做太多的建模,并在模型中包含可能没有必要的东西。您会发现这会产生更简单,更灵活的模型。

这引发了如何在模型更改时修改数据的问题。您通常会发现有一系列安全,简单的重构,您可以随身携带,就像您重构代码一样。在这种情况下,您需要向:TEACHES关系开始的所有节点添加标签。

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