2017-04-18 448 views
1

Cypher中的IF/ELSE语句的语法是否有任何更新?IF ... ELSE与Cypher Neo4J

我知道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, 
} 

我知道那并不考虑到上下文没有多大意义,但我基本上传入了一个可能包含或不包含参数的参考对象(或者参数存在且为NULL)。

我读的某处可能会有更新怎么样 一个“if/else”可能会在neo4j中处理,所以我真的只是想检查一下,看看有没有人知道“更好”的方式来处理这种情况。

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

同样,我知道我可以使用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" 
     ^

我也知道,我可以使用WITH...CASE如果我传回一个已知的价值,但不能做一个MATCH里面。

想要在查询顶部的CASE内部执行MATCH的原因之一是因为我希望查询失败,如果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) 
} 
+0

你能否重申这是一个单一的焦点问题? – cybersam

+0

只有一个问题。我怎样才能让它成为单一焦点? “Cypher中IF/ELSE语句的语法是否有任何更新?”如第一句所述。我只是试图去除与我的用例无关的不需要的“建议”。第一个代码块显示了我想要完成的工作,以便在我的请求中提供一些参考信息。 –

+0

另外,你是什么意思“我想查询失败,如果属性上的裁判存在,但匹配成功”? – cybersam

回答

4

APOC Procedures刚刚更新,支持conditional cypher execution。您需要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}, ... 
} 

在你的回报,地图投影是足以满足你的需求,你会得到一个物体的uuid如果如果不存在,则存在cl,或者为空client