2015-11-01 39 views
2

我期待他下面的查詢由給定的源節點創建節點(僅出口)和關係(1)和一個列表(2)這種方式:不能使用合併中的foreach對存在的節點

MERGE (p1:C9{userId: '1'}) WITH p1, [{userId:"2"}] AS users 
FOREACH (user IN users | MERGE 
((p1)-[r1:follow]->(:C9 {userId: user.userId}))) 

那是結果:

enter image description here

現在,如果我被交換節點ID這樣再次執行這個查詢:

MERGE (p1:C9{userId: '2'}) WITH p1, [{userId:"1"}] AS users 
    FOREACH (user IN users | MERGE 
    ((p1)-[r1:follow]->(:C9 {userId: user.userId}))) 

我們拿到的這款:

enter image description here

Neo4j的複製我的節點使用id = 1。我希望它在現有節點的情況下合併。

我期望看到只有兩個節點通過合併已有節點相互連接。

任何想法我應該修復?

謝謝, 射線。

回答

2

我通常會避免FOREACH時,我可以使用UNWIND,所以我會像這樣開始:

MERGE (p1:C9 {userId: '1'}) 
WITH p1, [{userId:"2"}] AS users 
UNWIND users AS user 
MERGE (p1)-[r1:follow]->(:C9 {userId: user.userId}) 

有時你也想你的節點創建從你的關係創建分開。如果你同時做這兩件事,我認爲Neo4j可以認爲你想要一個節點(包含屬性)和關係的獨特組合。

MERGE (p1:C9 {userId: '1'}) 
WITH p1, [{userId:"2"}] AS users 
UNWIND users AS user 
MERGE (p2:C9 {userId: user.userId}) 
MERGE (p1)-[r1:follow]->(p2) 
+0

感謝您的回覆。爲什麼在這種情況下放鬆會更好? – rayman

+0

'UNWIND'對我來說更容易推理。它也使它更清潔,因爲我可以有單獨的行,而不是'FOREACH'內的所有東西。最後,'FOREACH'裏面的子句只對我感覺不對......也許它只是感覺不到查詢語言。我知道這一切都很模糊;) –

+0

我還想到了一件事:如果你需要多個'MERGEs'或者'ON(MATCH | CREATE)SET'或者其他東西,那麼這些東西就是你扔進你的' FOREACH',但對我來說更加雜亂 –

0

可以內FOREACH使用MERGE

但是你必須瞭解MERGE的語義。它試圖MATCH一個完整的模式,如果它沒有找到它它將完全CREATE該模式。

你在你的情況下,你嘗試在p1的上下文內找到的模式,而不是全局的,如果沒有找到,它會在p1的上下文中創建它。

所以,如果你改變你的查詢:

MERGE (p1:C9{userId: '2'}) 
WITH p1, [{userId:"1"}] AS users 
FOREACH (user IN users | 
    MERGE (p2:C9 {userId: user.userId}) 
    MERGE (p1)-[r1:follow]->(p2) 
) 

即先創建p2再與MERGE的關係,它會起作用。

+0

現在我明白了。謝謝。在他的回答中,FOREACH與使用UNWIND作爲@Brian展示有什麼關係?性能方面?任何其他方面? – rayman