【问题标题】:neo4j delete a node in linked listneo4j 删除链表中的一个节点
【发布时间】:2018-06-10 07:55:21
【问题描述】:

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

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

这是结构示意图。

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

我曾考虑在子查询中使用 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-- 的答案最接近正确的解决方案,但是它无法删除列表末尾的节点并引发异常,因为它不检查 nextNode 是否存在于第二个 FOREACH 语句中。

它需要调整才能工作:

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

【问题讨论】:

  • 实现IF pattern matches THEN CREATE EDGE 非常简单,您只需使用类似:MATCH <pattern> CREATE (n1)-[:EDGE_TYPE]->(n2),其中n1n2 是模式中的节点。

标签: database neo4j cypher graph-databases cypher-3.1


【解决方案1】:

您可以使用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 中的过程apoc.do.when 用于conditional query execution

【讨论】:

  • 这无法删除最后一个节点。我已经对其进行了调整,现在它可以工作了。非常感谢。我在问题的末尾添加了调整后的答案。如果您想修改您的答案以检查第二个 foreach 中是否存在 nextNode,那么我将接受您的答案。再次非常感谢,我刚刚了解了 neo4j 中的管道 :-)
  • 是的,你是对的,我添加了一个修复程序和一个小插件。
【解决方案2】:

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

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 可能会导致异常, 类似于:

本应在 prevNode 找到一个节点,但没有找到 Some(NO_VALUE)

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

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)

【讨论】:

  • 如果你尝试删除列表中间的一个节点,例如第 3 个节点,会怎样?
  • 哇,很好看。我错过了传递nextNode。我再次测试了它,现在它似乎工作正常。
  • 这无法删除列表中间和末尾的节点。原因是第一个 MATCH 语句将始终失败,因为它假定要删除的节点始终是第一个节点。请注意,它始终具有用户节点的边缘。末端或中间的节点不能具有带有 :OWNS 标签的边缘。不过,请竖起大拇指。
猜你喜欢
  • 1970-01-01
  • 2011-06-06
  • 1970-01-01
  • 2010-12-29
  • 2014-04-27
  • 1970-01-01
相关资源
最近更新 更多