Cypher Linked LIst:如何通过索引取消移位和替换

时间:2015-10-23 16:03:05

标签: neo4j cypher

我正在尝试按照此处的建议使用Neo / Cypher创建链接列表结构:CYPHER store order of node relationships of the same label when I create

- (NSView*)frameView {
  return [[self contentView] superview];
}

但是我无法理解所需事件序列的语法,以便将新节点卸载到结构上或用不同的节点替换特定索引。

我感到困惑的是我需要添加新节点并修复使旧节点仍在链表结构中的结构的部分。每个类型(PARENTID_RELTYPE)只有一个源自父节点的关系;但是每个父母可以有不同类型的多种关系。子节点可以在LinkedList中多次显示,并且子节点可以在多个Parent的LinkedList中或在同一父节点但具有不同关系类型的LinkedList中。

因此,当我尝试取消移位时,可能会发生以下三种情况之一:

  1. PARENTID_RELTYPE

  2. 没有现有的儿童链接到父母
  3. 已存在通过PARENTID_RELTYPE链接到父级的子节点

  4. 已经存在一个通过PARENTID_RELTYPE链接到父节点的子节点,并且该子节点只是我尝试卸载到链表结构的子节点的副本(在这种情况下,预期结果是在链表的零和第一个索引中具有相同的子节点。

  5. 上面提到的答案网址有助于我理解如何阅读Neo / Cypher中的链表结构,但由于在cypher中处理条件的替代方法,我无法理解如何写入结构(并从他的结构中删除。)

    以下是我最初的尝试,但我对我需要的语法操作感到有些困惑。

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

    我非常感谢您提供的帮助。

2 个答案:

答案 0 :(得分:2)

[增订]

在以下查询中,为简单起见,我假装:

  • 我们按名称找到感兴趣的Parent节点。
  • 当前感兴趣的关系类型为Foo

一般说明:

  • OPTIONAL MATCH条款找到应该跟随孩子插入的兄弟姐妹(如果有的话)。
  • FOREACH子句负责将兄弟姐妹(如果有的话)与正在插入的孩子联系起来,然后删除与该兄弟姐妹的过时关系。


  1. 取消移动 Child id 123 Parent 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; 节点后面的Child

    id
  2. 插入 123 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; Child的{​​{1}}节点在索引4处(即,使其成为第5个孩子):

    Child
  3. 要{em>替换索引为4的id(即第5个孩子)123 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)。这只适用于您实际想要发生的情况,并且仅在NSString *pic =item.pic; if (pic) { if ([pic length]) { //Do some stuff } } 没有while ((rLine = sReader.ReadLine()) != null) { string text = rLine.Remove(rLine.IndexOf('|') - 1); //message | response string response = rLine.Remove(0, rLine.IndexOf('|') + 2) ; string realText = text.ToLower(); if (callback.Message.Contains(realText) || callback.Message.Contains(text)) { steamFriends.SendChatMessage(callback.Sender, EChatEntryType.ChatMsg, response); Console.WriteLine("Someone has messaged me, and I replied with an automated message."); sReader.Close(); return; } else { steamFriends.SendChatMessage(callback.Sender, EChatEntryType.ChatMsg, "I don't know what you mean. Could you maybe write it a bit differently? <3"); Console.WriteLine("Someone has messaged me, and it wasn't on my auto-response list: {0}",callback.Message); sReader.Close(); return; } } 以外的关系时才会成功。要探索如何满足更具体的需求,请提出一个新问题。

答案 1 :(得分:1)

如果我关注,您的节点可能属于多个链接列表。一个简单的“下一个”&#39;关系是不充分的,因为当列表交叉共享一个子节点 - &#39; next&#39;关系将拖动两个列表的所有下游节点。因此,您正在制作下一个&#39;通过添加父节点的id,每个列表唯一的关系。 (注意使用元数据ID可能会导致问题。)

所以你可能有一个id为1的父p1,以及一个独特的关系&#39; n_p1&#39;将孩子与孩子和孩子联系起来。你要添加的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;