首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用于将节点从一个列表结构移动到另一个列表结构的Cypher查询

用于将节点从一个列表结构移动到另一个列表结构的Cypher查询
EN

Stack Overflow用户
提问于 2020-03-11 16:39:34
回答 1查看 86关注 0票数 0

我们有以下结构,其中用户是起点,带有数字的节点被标记为邀请,其值指定它们的属性id

我正在寻找一种创建查询的方法,该查询将节点从VALID_INVITATIONS关系指向的列表移动到由INVALID_INVITATIONS指向的另一个列表。移动节点应首先在新列表中设置。

我想出了一个可行的解决方案,但由于缺乏对Cypher的知识和经验,我恳请社区为之提供帮助和改进。正如您将看到的那样,有许多命令式代码“hack”(情况下),而不是像Cypher所认为的那样是声明性的。我很感谢你的提示和建议。

代码语言:javascript
运行
复制
MATCH (u:User)
MATCH (u)-[:VALID_INVITATIONS|PREVIOUS*]->(current:Invitation{ id:3 })

//find (current) node's predecessor which might pointing on it through VALID_INVITATIONS or PREVIOUS relationships
OPTIONAL MATCH (u)-[oldValidRel:VALID_INVITATIONS]->(current)
OPTIONAL MATCH (predecessor:Invitation)-[oldPredecessorRel:PREVIOUS]->(current)
//find (current) node's subsequent node
OPTIONAL MATCH (current)-[oldSubsequentRel:PREVIOUS]->(subsequent:Invitation)

//first we re-create connections in list pointed by VALID_INVITATION relationship for consistency
WITH *, CASE subsequent WHEN NULL THEN [] ELSE [1] END AS hasSubsequent

//if (current) node is connected to (u) User we replace VALID_INVITATIONS relationship
FOREACH(_ IN CASE oldValidRel WHEN NULL THEN [] ELSE [1] END |
    DELETE oldValidRel

    //if (subsequent) node exist then we need to re-link it
    FOREACH(_ IN hasSubsequent |
        MERGE (u)-[:VALID_INVITATIONS]->(subsequent)
        DELETE oldSubsequentRel
    )
)

//following condition should be XOR with the one above (only one must be executed)
//if (current) node has another Invitation node as predecessor in list
FOREACH(_ IN CASE oldPredecessorRel WHEN NULL THEN [] ELSE [1] END | 
    DELETE oldPredecessorRel

    //if (subsequent) node exist then we need to re-link it
    FOREACH(_ IN hasSubsequent |
        MERGE (predecessor)-[:PREVIOUS]->(subsequent)
        DELETE oldSubsequentRel
    )
)

WITH u, current

//now it is time to move (current) node to beginning of the list pointed by  INVALID_INVITATIONS relationship
MERGE (u)-[:INVALID_INVITATIONS]->(current)
WITH u, current
//find obsolete oldRel:INVALID_INVITATIONS relationship
MATCH (current)<-[:INVALID_INVITATIONS]-(u)-[oldRel:INVALID_INVITATIONS]->(oldInv)
DELETE oldRel
//link (current) with previously "first" node in INVALID_INVITATIONS list
MERGE (current)-[:PREVIOUS]->(oldInv)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-13 08:00:16

在享受了一些“乐趣”和assisstance from @cybersam之后,我想出了一个更短的解决方案:

代码语言:javascript
运行
复制
MATCH (u:User)-[:VALID_INVITATIONS|PREVIOUS*]->(current:Invitation {id:4})
MATCH (predecessor)-[oldPredecessorRel:VALID_INVITATIONS|PREVIOUS]->(current)
OPTIONAL MATCH (current)-[oldSubsequentRel:PREVIOUS]->(subsequent)

CALL apoc.do.when(subsequent IS NOT NULL, "CALL apoc.create.relationship($p, $r, NULL, $s) YIELD rel RETURN rel", "", {p:predecessor, r:type(oldPredecessorRel), s:subsequent}) YIELD value

DELETE oldPredecessorRel, oldSubsequentRel

WITH u, current
MERGE (u)-[:INVALID_INVITATIONS]->(current)
WITH u, current
MATCH (oldInv)<-[oldRel:INVALID_INVITATIONS]-(u)-[:INVALID_INVITATIONS]->(current)
DELETE oldRel
MERGE (current)-[:PREVIOUS]->(oldInv)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60640755

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档