【问题标题】:CYPHER store order of node relationships of the same label when I create创建时相同标签的节点关系的CYPHER存储顺序
【发布时间】:2015-10-21 15:52:27
【问题描述】:

我有多个源自一个节点的关系。这些关系中的每一个都具有相同的标签。这些关系指向一个子节点(不一定是唯一的)。在我通过这个关系标签获取所有链接到父节点的子节点之后,我通过一个名为 trueindex 的关系属性对它们进行排序。然后我有一个节点数组,我的客户端可以按正确的排序顺序遍历这些节点。

当我尝试“push、pop、unshift 等...”到这个数组时,问题就来了。如果我想在订单的前面添加一个新的关系,我必须创建一个新的关系,使用它将父节点链接到子节点,然后将 0 值添加到关系的 trueindex 属性中。问题是已经存在一个 trueindex 值为 0 的关系,我需要执行某种 casecading 函数来增加所有其他关系的 trueindex (所有关系都来自同一个父节点的相同类型)。我正在尝试找到一种方法来免费获得这种“类似数组”的索引号功能

我能想到的唯一方法是首先删除源自父级的特定标签的所有关系。然后重写整个数组(以及所有将它们的 trueindex 加一的现有关系)以反映正确的顺序。这对于小情况来说很好,但是如果我计划让父节点有大量的关系,那么每次我想添加、按索引删除、弹出等时重写整个数组(关系集)是一个问题但仍保持源自父节点的关系顺序。

在创建新关系时,Neo4j 是否有某种关系功能可以按照正确的顺序写入?

非常感谢您提供的建议。

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    尝试将子节点保留在链表中。结构看起来像

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

    这会维护您的子节点的顺序,并允许您通过两种方式改进与结构的交互:

    1. 将新节点插入此结构仅涉及更改该节点所在位置的“之前”和“之后”关系,而不是整个结构。例如,要在c1c2 之间插入newc,请删除r2,创建newc 并创建从c1newcc2:NEXT 关系。与其他操作类似:您的所有更改现在都在结构内进行。

    2. 您使用关系及其类型来构建数据,而不是关系属性。这更灵活,而且几乎总是性能更高(有时性能更高)。

    要从此结构中读取单个子节点,您现在使用 trueindex 声明在链表中查找节点的深度,即

    MATCH (parent:Parent {parentId: 1234})-[:CHILDREN]->()-[:NEXT*3]->(child)
    RETURN child
    

    并检索父级及其所有子级

    MATCH (parent:Parent {parentId: 1234})-[:CHILDREN|NEXT*]->(child)
    RETURN parent, COLLECT(child) as children
    

    【讨论】:

    • 如果一个子节点可以有多个父节点(即出现在同一关系标签的多个“数组”中),那么您如何管理 :Next 标签以反映每个父节点的成员资格?
    • @BenjaminMcFerren 当链表相互交叉时,即共享一个节点,那么要标记每个唯一链表的NEXT关系,可以将父节点的id作为每个链表的NEXT属性.
    • 谢谢@S.D.和贾德伯格。我现在正在尝试根据您的建议编写一个 unshift 查询,但我在条件部分遇到了问题。我尝试了 CASE,但它似乎只与 RETURN 或 WITH 具体值相关,而不是允许我根据条件执行 CREATE。当这产生零结果时,我正在尝试创建链表中的第一个链接: MATCH a-[rel:RELTYPE]->b n.id={_parentnodeid} 如果它产生的结果为 1,我想执行上述答案中描述的链表操作。非常感谢您对此的帮助
    【解决方案2】:

    您可以先使用SET 来增加或减少现有关系的属性。

    以下示例移动现有关系的trueIndex,并在索引 0 处推送新关系(到现有子节点):

    MATCH (n:Root)-[r:HAS]->(c:Child) 
    WHERE id(n) = 0 
    SET r.trueIndex = r.trueIndex + 1
    WITH n, min(r.trueIndex) as indexStart, max(r.trueIndex) as indexEnd
    CREATE (n)-[r:HAS  {trueIndex:(indexStart-1)}]->(c:Child)
    WHERE id(c) = 12
    RETURN n,r,c
    

    您可以根据需要修改查询。

    设计方面,我同意@jjaderberg 的回答,保留一个链表来表示一个数组会更简单。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-26
      • 1970-01-01
      • 2020-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多