neo4j:单向/双向关系?

时间:2013-06-01 19:22:39

标签: nosql neo4j relationship

所以我研究了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之间)建立关系?

1 个答案:

答案 0 :(得分:33)

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

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

相反,如果关系的语义确实具有类似于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