我正在学习nosql数据库和neo4j。我想知道何时应该在节点或链接中定义关系?
例如:
(teacher)-[:TEACHS]->(student)
或
(Person)-[:TEACHS]->(Person)
我知道这不是我的问题的好例子。但我认为它必定是Neo4j或图论中的一个重要主题,但我找不到关于这个主题的例子或讨论......
答案 0 :(得分:2)
我想说这取决于您的域名。两个
(teacher:Person:Teacher)-[:TEACHES]->(student:Person:Student)
定义三个标签 - Person
,Teacher
和Student
。这有助于定义遍历。但是,如果您想在关系级别修剪遍历,也可以执行
(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