2013-06-01 165 views
9

因此,我研究了neo4j,我可能会在即将推出的项目中使用它,因为它的数据模型可能非常适合我的项目。我查看了文档,但我仍然需要回答这个问题:neo4j:单向/双向关系?

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

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

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

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

但我喜欢恐怖电影等等...

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

我需要这种关系是单向的,所以如果我查询“谁不某甲要杀人?”如果我询问“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之间)建模?

回答

29

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 

找到谁想要杀了所有的人:

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

现货,谢谢! – joschua011

+3

即使两年后,这仍然是非常有价值的。在文档中找不到这个答案。它很可能在那里,但也许他们措辞的方式使它很难找到。 –