IF ... ELSE与Cypher Neo4J

Sen*_*lez 3 neo4j cypher

IF/ELSECypher 中的语句语法是否已更新?

我知道CASEFOREACH“黑客”,但它们是如此难看:)

我想用可选参数做一些事情,例如:

CASE WHEN exists($refs.client) THEN MATCH (cl:client {uuid: $refs.client}) END
...

// and later use it like
CASE WHEN exists(cl) THEN DELETE tcr MERGE (t)-[:references]->(cl) END

// and again in my return
RETURN {
  client: CASE WHEN exists(cl) THEN {uuid: cl.uuid} ELSE NULL END,
}
Run Code Online (Sandbox Code Playgroud)

我知道给定上下文并没有多大意义,但我基本上是传递一个可能包含或不包含参数(或参数存在且为NULL)的refs对象。

在我读过的某个地方,可能会更新neo4j中如何处理“ if / else”,所以我真的只想检查一下,看看是否有人知道“更聪明”的方式来处理这种情况。

当前,我只用代码处理所有查询并运行一堆较小的查询,但是它需要重复查找才能创建和删除引用。我想将其全部移动到一个较大的查询中,以便可以使用变量引用。

同样,我知道我可以使用FOREACH...CASE,但是当有很多像这样的小案例时,它就会变得多毛。

当前错误是

{ Error: Invalid input 'S': expected 'l/L' (line 7, column 9 (offset: 246))
"      CASE true WHEN exists($refs.client) THEN MATCH (cl:client {uuid: $refs.client}) END"
         ^
Run Code Online (Sandbox Code Playgroud)

我还知道,WITH...CASE如果我传回一个已知值,但无法在其MATCH内部进行操作,则可以使用。

想要在查询顶部的MATCH内部进行操作的原因之一CASE是,因为我希望如果refs上的属性存在但查询不成功,查询将失败MATCH。使用OPTIONAL MATCH不能完成此任务。

编辑哦,也...我正在审查使用, MATCH (cl:client {uuid: $refs.client}) WHERE exists($refs.client)但我记得那不能正常工作。

编辑我可以做,MATCH...WHERE exists()但是以后如果我做不到,那是徒劳的MERGE WHERE exists()

编辑作为参考,以显示为什么我要询问IF / ELSE,这是我正在查看的查询。我已经根据上面的示例对其进行了修改,因此不会出错。

MATCH (u:user {uuid: $uid})-[:allowed_to {read: true}]->(c:company {uuid: $cid})
MATCH (t:timesheet {uuid: $tid})<-[:owns]-(:timesheets)<-[:owns]-(u)

// Make sure the incoming references are valid or fail query
// Here, I'd like only do a match IF $refs.client exists and IS NOT NULL. If it is null or does not exist, I don't want the query to fail. OPTIONAL MATCH will not fail if the value is passed in is invalid but will simply return NULL. Which is why IF/ELSE (or CASE) would be helpful here.
MATCH (cl:client {uuid: $refs.client})
MATCH (ca:case {uuid: $refs.case})
MATCH (s:step {uuid: $refs.step})
MATCH (n:note {uuid: $refs.note})

// clone timesheet entry to a revision
CREATE (t)-[:assembled_with]->(r:revision)
SET r = t, r.created_at = $data.updated_at

WITH *

// Get the old references
MATCH (t)-[tcr:references]->(rc:client)
MATCH (t)-[tcar:references]->(rca:case)
MATCH (t)-[tsr:references]->(rs:step)
MATCH (t)-[tnr:references]->(rn:note)

// Copy old references to revision (won't create new relationships with NULL)
MERGE (r)-[:references]->(rc)
MERGE (r)-[:references]->(rca)
MERGE (r)-[:references]->(rs)
MERGE (r)-[:references]->(rn)

// Update the current timesheet with new data
SET t += $data

// If new references are incoming, delete the old ones and update for new ones
DELETE tcr
DELETE tcar
DELETE tsr
DELETE tnr
MERGE (t)-[:references]->(cl)
MERGE (t)-[:references]->(ca)
MERGE (t)-[:references]->(s)
MERGE (t)-[:references]->(n)

WITH *

// Get the new count of revisions
MATCH (t)-[:assembled_with]->(_r:revision)

RETURN {
  uuid: t.uuid,
  start: t.start,
  end: t.end,
  description: t.description,
  client: CASE WHEN exists(cl.uuid) THEN {uuid: cl.uuid} ELSE NULL END,
  case: CASE WHEN exists(ca.uuid) THEN {uuid: ca.uuid} ELSE NULL END,
  step: CASE WHEN exists(s.uuid) THEN {uuid: s.uuid} ELSE NULL END,
  note: CASE WHEN exists(n.uuid) THEN {uuid: n.uuid} ELSE NULL END,
  revisions: count(_r)
}
Run Code Online (Sandbox Code Playgroud)

Inv*_*con 6

刚刚更新了APOC程序,以支持有条件的密码执行。您需要版本3.1.3.7或更高版本(如果使用Neo4j 3.1.x),或者版本3.2.0.3或更高版本(如果使用Neo4j 3.2.x)。

这是您使用新过程提到的某些情况的示例:

CALL apoc.when($refs.client IS NOT NULL, 
 "MATCH (cl:client {uuid: refs.client}) RETURN cl", '', {refs:$refs}) YIELD value
WITH value.cl as cl  // which might be null...
...

...
CALL apoc.do.when(cl IS NOT NULL, 
 "DELETE tcr 
  MERGE (t)-[:references]->(cl)", '', {tcr:tcr, t:t, cl:cl}) YIELD value
...

...
RETURN {
  client: cl {.uuid}, ...
}
Run Code Online (Sandbox Code Playgroud)

作为回报,地图投影足以满足您的需求,如果cl存在uuid,则将获得一个对象,如果不存在,client则将返回null 。