IF/ELSECypher 中的语句语法是否已更新?
我知道CASE和FOREACH“黑客”,但它们是如此难看:)
我想用可选参数做一些事情,例如:
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)
刚刚更新了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 。