neo4j删除链表中的一个节点

neo4j delete a node in linked list

我有一个属于某个用户的帖子列表。帖子结构为属于给定用户的链表。

我要在保留数据结构的同时删除给定的节点。

这是结构图。

在我的列表尝试中,我编写了下面的查询,但是它不起作用,因为 MATCH 在子查询中没有 return 任何内容。

我考虑过在子查询中使用 OPTIONAL MATCH,但这会导致异常。

MATCH(node:Post)
WHERE ID(node) = 2749
WITH node
MATCH(user:User)-[:OWNS]->(node)-[:PREV]->(nextNode:Post)
CREATE(user)-[:OWNS]->(nextNode)
WITH node
MATCH(prevNode:Post)-[:PREV]->(node)-[:PREV]->(nextNode:Post)
CREATE(prevNode)-[:PREV]->(nextNode)
WITH node
DETACH DELETE node

我假设如果子查询中的模式失败,则子查询的其余部分将被跳过,下一个子查询仍将执行。但似乎整个事情并没有得到执行。

我们如何在不停止执行的情况下在子查询中执行如下所示的操作。

IF pattern matches
THEN 
   CREATE EDGE 
IF pattern matches
THEN
   Do something else

解决方案

stdob--的答案是最接近正确的解决方案,但是它无法删除列表末尾的节点并抛出异常,因为它不检查第二个 FOREACH 中是否存在 nextNode声明。

它需要调整才能工作:

MATCH(node:Post) WHERE ID(node) = 2813

OPTIONAL MATCH (user:User)-[:OWNS]->(node)
OPTIONAL MATCH (node)-[:PREV]->(nextNode:Post)
OPTIONAL MATCH (prevNode:Post)-[:PREV]->(node)

FOREACH (ith in CASE 
    WHEN user IS NOT NULL AND nextNode IS NOT NULL 
    THEN [1] 
    ELSE [] 
    END | CREATE (user)-[:OWNS]->(nextNode) 
)

FOREACH (ith in CASE WHEN 
    prevNode IS NOT NULL AND nextNode IS NOT NULL 
    THEN [1] ELSE [] 
    END | CREATE (prevNode)-[:PREV]->(nextNode)
)

DETACH DELETE node

您可以使用 OPTIONAL MATCHFOREACHCASE 的组合:

MATCH(node:Post) WHERE ID(node) = 2749

OPTIONAL MATCH (user:User)-[:OWNS]->(node)
OPTIONAL MATCH (node)-[:PREV]->(nextNode:Post)
OPTIONAL MATCH (prevNode:Post)-[:PREV]->(node)

FOREACH (ith in CASE WHEN 
                     NOT user IS NULL AND 
                     NOT nextNode IS NULL 
                THEN [1] ELSE [] END |
    CREATE (user)-[:OWNS]->(nextNode) 
)

FOREACH (ith in CASE WHEN 
                     NOT prevNode IS NULL AND
                     NOT nextNode IS NULL
                THEN [1] ELSE [] END |
    CREATE (prevNode)-[:PREV]->(nextNode)
)

DETACH DELETE node

更新:您还可以使用 apoc.library for the conditional query execution.

中的程序 apoc.do.when

我使用以下查询重新创建了您的数据集:

CREATE
  (u:User {name: 'Alice'})-[:OWNS]->
  (p1:Post {number: 1})-[:PREV]->
  (p2:Post {number: 2})-[:PREV]->
  (p3:Post {number: 3})-[:PREV]->
  (p4:Post {number: 4})-[:PREV]->
  (p5:Post)

如您所述,使用 OPTIONAL MATCH 会导致异常, 类似于:

Expected to find a node at prevNode but found nothing Some(NO_VALUE)

但是,您可以解决此问题,方法是首先执行 DELETE,然后使用 WITH 子句传递值,并且仅 运行 CREATE 如果OPTIONAL MATCH 子句引入的变量 IS NOT NULL.

MATCH (user:User)-[:OWNS]->(node)-[:PREV]->(nextNode:Post)
WHERE node.number = 1
CREATE (user)-[:OWNS]->(nextNode)
WITH node, nextNode
OPTIONAL MATCH (prevNode:Post)-[:PREV]->(node)
DETACH DELETE node
WITH prevNode, nextNode
WHERE prevNode IS NOT NULL
CREATE (prevNode)-[:PREV]->(nextNode)