2015-10-23 19 views
0

我試圖創建一個新/ Cypher支架鏈表結構,每recomendation這裏替換:CYPHER store order of node relationships of the same label when I create暗號鏈表:如何不印字和指數

(p:Parent)-[r1:PARENTID_RELTYPE]->(c1:Child)-[r2:PARENTID_RELTYPE]->(c2:Child)-[r3:PARENTID_RELTYPE]->(c3:Child) 

但我無法理解的語法所需的事件順序,以便將新節點移位到結構上或用不同的節點替換特定的索引。

我感到困惑的地方是我需要添加新節點並修復使舊節點仍在鏈表結構內的結構。每個類型(PARENTID_RELTYPE)應該只有一個來自父節點的關係;但是,每個父母可以有不同類型的多種關係。子節點可以在LinkedList中多次顯示,並且子節點可以顯示在多個父代的LinkedList中,或者位於同一父代的LinkedList中,但是具有不同的關係類型。

  1. 現時沒有孩子,通過

  2. 已經有一個子節點鏈接的PARENTID_RELTYPE鏈接到父:

    所以,當我嘗試不印字以下三種情況之一可能發生父母通過PARENTID_RELTYPE

  3. 已經存在通過PARENTID_RELTYPE鏈接到父節點的子節點,並且該子節點僅僅是子節點的副本我試圖解除ontift ont o鏈表結構(在這種情況下,預期的結果是在鏈表的零和第一個索引中具有相同的子節點)。

上述答案的網址可以幫助我大大地瞭解如何閱讀新/ Cypher支架鏈表結構,但因爲其條件語句在暗號處理的另一種方式,我無法理解怎麼寫到結構(並且從結構中刪除)。

以下是我最初的嘗試,但我對我需要的語法有些困惑。

MATCH (a:%s {id: {_parentnodeid}}), (b:%s {id: {_id}}) 
MERGE a-[relold:%s]->b 
    ON CREATE 
    SET relold.metadata = {_metaData} 
    ON MATCH 
    ... 

我非常感謝您的幫助,您可以提供。

回答

2

[增訂]

在下面的查詢,爲簡單起見,我假裝說:

  • 我們找到的名字感興趣的Parent節點。
  • 當前利益的關係類型是Foo

一般注意事項:

  • OPTIONAL MATCH條款找到兄弟,如果有的話,應該遵循插入孩子。
  • FOREACH子句負責將該兄弟(如果有)鏈接到要插入的子項,然後刪除與該兄弟的過時關係。


  1. 不印字Child具有123一個idParent節點後右:

    MATCH (p:Parent {name:"Fred"}) 
    OPTIONAL MATCH (p)-[r:Foo]->(c:Child) 
    WITH p, r, COLLECT(c) AS cs 
    MERGE (cNew:Child {id:123}) 
    CREATE (p)-[rNew:Foo]->(cNew) 
    FOREACH (x IN cs | 
        CREATE (cNew)-[:Foo]->(x) 
        DELETE r) 
    RETURN p, rNew, cNew; 
    
  2. 插入具有的Child節點在指數4 (即,使其成爲第五子):

    MATCH (p:Parent {name:"Fred"}) 
    MATCH (p)-[:Foo*3]->()-[r:Foo]->(c:Child) 
    OPTIONAL MATCH (c)-[r1:Foo]->(c1:Child) 
    WITH c, r1, COLLECT(c1) AS c1s 
    MERGE (cNew:Child {id:123}) 
    CREATE (c)-[rNew:Foo]->(cNew) 
    FOREACH (x IN c1s | 
        CREATE (cNew)-[:Foo]->(x) 
        DELETE r1) 
    RETURN c, rNew, cNew; 
    
  3. 123id更換Child在與Child指數4(即第5子):

    MATCH (p:Parent { name:"Fred" }) 
    MATCH (p)-[:Foo*4]->(c0)-[r:Foo]->(c:Child) 
    OPTIONAL MATCH (c)-[r1:Foo]->(c1:Child) 
    WITH c0, r, c, r1, COLLECT(c1) AS c1s 
    MERGE (cNew:Child { id:123 }) 
    CREATE (c0)-[rNew:Foo]->(cNew) 
    DELETE r, c 
    FOREACH (x IN c1s | 
        CREATE (cNew)-[:Foo]->(x) 
        DELETE r1) 
    RETURN c0, rNew, cNew; 
    

    注意:DELETE r, c子句總是刪除正在替換的節點(c)。這只是合適的,如果這是你真正想要的事情發生,如果c沒有比r其他關係,纔會成功。要探索如何解決更具體的需求,請提出一個新問題。

+0

感謝各位大大的幫助cybersam。我一直在嘗試這些,我成功地使用了1.unshift。對於2.replace,你爲什麼使用MATCH(p) - [:Foo * 4 ..4] - >() - [r:Foo] - >(c:Child)而不是MATCH(p) - [r:Foo * 4] - >(c:Child)? 此外,有沒有辦法在索引4處沒有節點的情況下回退?在密碼查詢將填充空白的情況下,使用一些替代靜態屬性/標籤在索引0到3創建節點,並最終在索引4創建預期節點?或者如果在索引0處已經有一個與關係Foo鏈接的子節點,則在索引1至3創建節點? –

+0

另外,如果MATCH(p) - [r:Foo * 0] - >(c:Child)不會產生索引0的結果,查詢是否可以返回並且(不移位)是否可以創建我們最初計劃在索引處創建的節點關係0? –

+0

我看到#2是* insert *,而不是* replace *。我會更新我的答案。 – cybersam

1

如果我關注,您的節點可能屬於多個鏈接列表。一個簡單的'下一個'關係是不夠的,因爲當列表交叉共享一個子節點時,'下一個'關係將拖拽兩個列表的所有下游節點。因此,通過添加父節點的ID,您可以使每個列表的「下一個」關係具有唯一性。 (注意使用元數據ID可能會導致問題在後面。)

因此,您可能有一個父p1,其id = 1,並且有一個唯一關係'n_p1'來鏈接其子元素,以及一個子元素'c'你想添加的ID = 21。

對於沒有孩子,你可以通過添加新的孩子家長:

MATCH (c {id:21}), (p {id:1}) WHERE NOT p-[:n_p1]->() MERGE p-[:n_p1]->c 

而且如果家長有一個或更多的孩子,找到最後一個,這不是一樣的一個添加:

MATCH (c {id:21}), (p {id:1})-[:n_p1*1..5]->(cn) WHERE NOT cn-[:n_p1]->() AND NOT cn.id=c.id MERGE cn-[:n_p1]->c 

其他人可能有更好的辦法,但你可以聯合在一起。記住一個UNION的部分必須返回相同的列,所以只需返回新的子c。整個事情可能是這樣的:

MATCH (c {id:21}), (p {id:1}) WHERE NOT p-[:n_p1]->() MERGE p-[:n_p1]->c return c UNION MATCH (c {id:21}), (p {id:1})-[:n_p1*1..5]->(cn) WHERE NOT cn-[:n_p1]->() AND NOT cn.id=c.id MERGE cn-[:n_p1]->c return c;