2017-04-18 151 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