Cypher Neo4J-带MERGE的CASE表达式

Cypher Neo4J-带MERGE的CASE表达式,merge,neo4j,logic,case,cypher,Merge,Neo4j,Logic,Case,Cypher,我试图在Cypher中实现逻辑,其中,基于特定条件(CASE语句),我将创建一些节点和关系;代码如下 MATCH (g:Game)-[:PLAYER]->(u:User)-[r1:AT]->(b1:Block)-[:NEXT]->(b2:Block) WHERE g.game_id='G222' and u.email_id = 'xyz@example.com' and b1.block_id='16' SET r1.status='Skipped', r1.enddat

我试图在Cypher中实现逻辑,其中,基于特定条件(
CASE
语句),我将创建一些节点和关系;代码如下

MATCH (g:Game)-[:PLAYER]->(u:User)-[r1:AT]->(b1:Block)-[:NEXT]->(b2:Block) 
WHERE g.game_id='G222' and u.email_id = 'xyz@example.com' and b1.block_id='16' 
SET r1.status='Skipped', r1.enddate=20141225
WITH u, b2,b1, g, r1
SET b1.test = CASE b2.fork 
WHEN 'y' THEN
     MERGE (u)-[r2:STAGE {startdate:20141225, enddate:'99999999', status:'InProgress'}]->(b2     {fork:'fail'}) RETURN 1
ELSE 
     MERGE (u)-[r2:STAGE {startdate:20141225, enddate:'99999999', status:'InProgress'}]->(b2)   RETURN 2
END
WITH u, g
MATCH (u)-[:TIME]->(h:Time)<-[:TIME]-(g)
SET h.after = 0
SET h.before = h.before + 1
MATCH(g:Game)-[:PLAYER]->(u:User)-[r1:AT]->(b1:Block)-[:NEXT]->(b2:Block)
其中g.game_id='G222'和u.email_id='2'xyz@example.com'和b1.块_id='16'
设置r1.status='Skipped',r1.enddate=20141225
有u,b2,b1,g,r1
设置b1.test=案例b2.fork
什么时候“y”呢
合并(u)-[r2:STAGE{startdate:20141225,enddate:'9999999',status:'InProgress'}]->(b2{fork:'fail'})返回1
其他的
合并(u)-[r2:STAGE{startdate:20141225,enddate:'9999999',状态:'InProgress'}]>(b2)返回2
结束
用u,g

匹配(u)-[:TIME]->(h:TIME)要执行条件写入操作,需要使用
FOREACH
技巧。使用
CASE
可以返回一个单元素数组或一个空数组
FOREACH
迭代
CASE
表达式,因此有条件地执行操作。如果您还想要一个
ELSE
零件,则需要在
案例中使用相反的条件来创建另一个
FOREACH
。例如

WHEN 'y' THEN
   MERGE (u)-[r2:STAGE {startdate:20141225, enddate:'99999999', status:'InProgress'}]->(b2     {fork:'fail'}) RETURN 1
ELSE 
    MERGE (u)-[r2:STAGE {startdate:20141225, enddate:'99999999', status:'InProgress'}]->(b2)   RETURN 2
END
使用


另请参见此部分。

修复了以下问题

WITH u, b2,b1, g, r1, CASE  WHEN (b1.fork='y' and b2.fork='success') or (b1.fork='n') or   (b1.fork='success') THEN ['ok'] ELSE [] END as array1
FOREACH (el1 in array1 | MERGE (u)-[r2:STAGE {startdate:20141225, enddate:99999999, status:'InProgress'}]->(b2))
i、 e.创建一个虚拟数组的用例,该数组在某种程度上具有匹配匹配计数的虚拟元素,然后使用FOREACH遍历结果

再次感谢Stefan的想法


Deepesh

虽然这个答案对我有帮助,但我发现语法很难理解。所以我写了自己的答案。在这里,我读取一个tsv文件并生成多种类型的边

LOAD CSV WITH HEADERS FROM 'file:///data.tsv' AS r FIELDTERMINATOR '\t'
WITH r.movie_id as movie_id, r.person_id as person_id, r.category as category
MATCH (p:Person {person_id:person_id})
MATCH (m:Movie {movie_id:movie_id})
FOREACH (_ IN CASE WHEN category='actress' THEN [1] ELSE [] END |
  MERGE (p)-[:ACTRESS {}]->(m)
)
FOREACH (_ IN CASE WHEN category='director' THEN [1] ELSE [] END |
  MERGE (p)-[:DIRECTOR {}]->(m)
)    
FOREACH (_ IN CASE WHEN category='cinematographer' THEN [1] ELSE [] END |
  MERGE (p)-[:CINEMATOGRAPHER {}]->(m)
)
FOREACH (_ IN CASE WHEN category='actor' THEN [1] ELSE [] END |
  MERGE (p)-[:ACTOR {}]->(m)
)
这里的
\uuu
是一个变量,它只是APOC插件支持的cypher语法的一个必要条件,在任何地方都没有使用,现在我们可以避免使用
FOREACH
解决方法

例如,您可以执行以下操作:

MATCH (g:Game)-[:PLAYER]->(u:User)-[r1:AT]->(b1:Block)-[:NEXT]->(b2:Block) 
WHERE g.game_id='G222' AND u.email_id = 'xyz@example.com' AND b1.block_id='16' 
SET r1.status='Skipped', r1.enddate=20141225
WITH u, b2, g
CALL apoc.do.when(
  b2.fork = 'y',
  "MERGE (u)-[:STAGE {startdate:20141225, enddate:'99999999', status:'InProgress'}]->(b2     {fork:'fail'})",
  "MERGE (u)-[:STAGE {startdate:20141225, enddate:'99999999', status:'InProgress'}]->(b2)",
  {u: u, b2: b2}) YIELD value
WITH u, g
MATCH (u)-[:TIME]->(h:Time)<-[:TIME]-(g)
SET h.after = 0
SET h.before = h.before + 1
MATCH(g:Game)-[:PLAYER]->(u:User)-[r1:AT]->(b1:Block)-[:NEXT]->(b2:Block)
其中g.game_id='G222'和u.email_id='2'xyz@example.com'和b1.块_id='16'
设置r1.status='Skipped',r1.enddate=20141225
用u,b2,g
什么时候打电话给apoc.do(
b2.fork='y',
“合并(u)-[:阶段{startdate:20141225,enddate:'9999999',状态:'InProgress'}]>(b2{fork:'fail'})”,
“合并(u)-[:阶段{起始日期:20141225,结束日期:'9999999',状态:'InProgress'}]>(b2)”,
{u:u,b2:b2})屈服值
用u,g

MATCH(u)-[:TIME]->(h:TIME)谢谢Stefan,是的,你是对的,似乎我们需要使用FOREACH,我还提到了你在StackOverflow中的一篇文章,逻辑最后是这样的,u,b2,b1,g,r1,CASE WHEN(b1.fork='y'和b2.fork='success')或(b1.fork='n')或(b1.fork='success'),然后['ok']ELSE[]结束为array1 FOREACH(在array1 | MERGE(u)-[r2:STAGE{startdate:20141225,enddate:9999999,status:'InProgress}]->(b2))这是一个很好的技巧,但是你能解释一下
然后[1]ELSE[]
的含义吗,还有什么是
ignoreMe
(对不起,我不能忽略你)?密码没有更新让我们忘记这个黑客吗?我真的很想读到,这个回复在2018年已经过时了。@HerrIvan这仍然是有条件合并的唯一方式吗?@bigmadwolf:是的。这是我一年前的问题。但是从那以后就没有答案了。。。也许Stefan Armburster更清楚。如果你不把你的长期业务逻辑放在CQL中,它会更整洁。
MATCH (g:Game)-[:PLAYER]->(u:User)-[r1:AT]->(b1:Block)-[:NEXT]->(b2:Block) 
WHERE g.game_id='G222' AND u.email_id = 'xyz@example.com' AND b1.block_id='16' 
SET r1.status='Skipped', r1.enddate=20141225
WITH u, b2, g
CALL apoc.do.when(
  b2.fork = 'y',
  "MERGE (u)-[:STAGE {startdate:20141225, enddate:'99999999', status:'InProgress'}]->(b2     {fork:'fail'})",
  "MERGE (u)-[:STAGE {startdate:20141225, enddate:'99999999', status:'InProgress'}]->(b2)",
  {u: u, b2: b2}) YIELD value
WITH u, g
MATCH (u)-[:TIME]->(h:Time)<-[:TIME]-(g)
SET h.after = 0
SET h.before = h.before + 1