18

所以我研究了 neo4j,我可能会在即将到来的项目中使用它,因为它的数据模型可能非常适合我的项目。我浏览了文档,但我仍然需要这个问题的答案:

我可以将关系设置为单向的吗?

似乎neo4j 的人喜欢电影,所以让我们继续。如果我有这样的图表:

Actor A -> [:Acts in] -> Movie B

那么方向很明显,因为节点是不同的类型。

但是我喜欢恐怖片,所以...

Person A -> [:wants_to_kill] -> Person B

我需要这种关系是单向的,所以如果我查询“A 想杀谁?” 如果我查询“B 想杀谁?”,我得到了 B。我什么都得不到。

有时我仍然需要关系是双向的

像:

Person A <-[:has_met] -> Person B

...这很明显。

文档说:

Relationships are equally well traversed in either direction. This means that there is
no need to add duplicate relationships in the opposite direction (with regard to 
traversal or performance).

While relationships always have a direction, you can ignore the direction where it is 
not useful in your application.

所以文档说,默认情况下,关系有一个方向,如果我愿意,我可以忽略它。

现在事情变得复杂了:

考虑下图(并注意箭头)

Person A <- [:wants_to_kill] -> Person B
Person B -> [:wants_to_kill] -> Person C
Person C -> [:wants_to_kill] -> Person A

如果我忽略所有指示,[:wants_to_kill]我会得到“A / C 想杀死谁?”的错误结果。如果我知道我必须忽略哪些,我就不会进行查询。

那么我可以以某种方式将关系设置为双向(在创建它们时),还是应该用两个关系(在人 A 和 B 之间)来建模?

4

1 回答 1

43

Neo4j 中的关系总是有方向的。如果关系类型的语义不包含方向,例如has_met从您的示例中,那么最好在创建关系时应用任意方向。然后通过使用密码中的“双向”(没有“大于/小于”字符)符号来完成查询:

start ... match (a)-[:HAS_MET]-(b) ....

相反,如果一个关系的语义确实有类似 your 的方向wants_to_kill,则需要使用两个关系来表示 a 和 b 想要杀死另一个,反之亦然。对于上面的示例,您需要有 4 个关系:

Person A -[:wants_to_kill]-> Person B
Person B -[:wants_to_kill]-> Person A
Person B -[:wants_to_kill]-> Person C
Person C -[:wants_to_kill]-> Person A

要找到 A 想要杀死你的所有人,请执行以下操作:

start a=node:node_auto_index(name='A') match a-[:wants_to_kill]->victims_of_a return victims_of_a

要找到所有想要杀死 A 的人:

start a=node:node_auto_index(name='A') match murderer_of_a-[:wants_to_kill]->a return murderer_of_a
于 2013-06-01T20:42:38.197 回答