Neo4j / Cypher - 基于count(或任何先前的查询语句)的条件set / create / etc语句

时间:2017-06-07 01:10:57

标签: neo4j cypher

你如何根据前一行的结果有条件地做一个SET(或其他任何东西)?所以例如下面的查询(它不起作用),我正在尝试根据计数是否为1来更新某些东西(否则不会这样做)。查询不喜欢那之后的语句,因此这就是发生错误的地方。我已经尝试过使用WHERE子句但是还没有运气。

有没有其他方法可以在一个查询中完成我在下面尝试做的事情?

MATCH (n:Thing { name: 'asdf' })
OPTIONAL MATCH (p:Thing)-[:HAS_CHILD]->(n)
OPTIONAL MATCH (c)<-[:HAS_CHILD]-(p:Thing)
WITH c, p, n,
CASE count(c)
WHEN 1
THEN SET p.btogstate = 'closed'
DETACH DELETE n

更新

基于类似的帖子尝试以下但仍然没有运气:

MATCH (n:Thing { name: 'asdf' })
OPTIONAL MATCH (p:Thing)-[:HAS_CHILD]->(n)
OPTIONAL MATCH (c)<-[:HAS_CHILD]-(p:Thing)
WITH c, p, n,
CASE WHEN count(c) = 1 then [1] else [] end as countOne
FOREACH (x in countOne | SET p.btogstate = 'closed'
DETACH DELETE n

更新2(最终)

虽然cybersam的解决方案在某种特定情况下起作用,但由于我仍然不理解的原因,以下是唯一最终适用于我的特定情况的东西,所以这里适用于任何可能遇到类似怪异的人。主要区别在于,我没有使用count来查看父节点是否有多个子节点,而是进行了另一个匹配,以查看是否还有其他任何父节点的子节点不是最初匹配的孩子(即其中n&lt;&gt; y)。如果没有(即y为null)则更新属性,如果有(即y不为空)则除了删除n之外不做任何事情:

MATCH (n:Thing { name: 'asdf' })
OPTIONAL MATCH (p:Thing)-[:HAS_CHILD]->(n)
with p, n
OPTIONAL MATCH (p)-[:HAS_CHILD]->(y)
WHERE n<>y
WITH n, y, p,
CASE WHEN y IS NULL then [1] else [] end as countOne
FOREACH (x in countOne | SET p.btogstate = 'closed')
DETACH DELETE n;

2 个答案:

答案 0 :(得分:1)

试试这个:

MATCH (n:Thing { name: 'asdf' })
OPTIONAL MATCH (p:Thing)-[:HAS_CHILD]->(n)
OPTIONAL MATCH (c)<-[:HAS_CHILD]-(p:Thing)
WITH c, p, n
FOREACH(x IN (CASE WHEN c IS NULL THEN [] else [1] END) |
  DETACH DELETE n
)

基于this Mark Needham帖子(Neo4j:LOAD CSV - 处理条件)。

答案 1 :(得分:1)

这应该有效:

MATCH (n:Thing { name: 'asdf' })
OPTIONAL MATCH (c)<-[:HAS_CHILD]-(p:Thing)-[:HAS_CHILD]->(n)
WITH p, n,
  CASE WHEN COUNT(c) = 1 then [1] else [] end as countOne
FOREACH (x in countOne | SET p.btogstate = 'closed')
DETACH DELETE n;

请注意,与原始查询不同,WITH子句本身不包含c,因为这会阻止聚合函数COUNT按预期工作(在这种情况下,如果可选匹配找到任何匹配,则始终的计数值为1。