2013-06-01 163 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

即使兩年後,這仍然是非常有價值的。在文檔中找不到這個答案。它很可能在那裏,但也許他們措辭的方式使它很難找到。 –