2014-12-20 19 views
7

Sto cercando di implementare la logica in Cypher in cui, in base a una particolare condizione (CASE Statement), creerei alcuni nodi e relazioni; il codice è come sottoCypher Neo4J - CASE Espressione con MERGE

MATCH (g:Game)-[:PLAYER]->(u:User)-[r1:AT]->(b1:Block)-[:NEXT]->(b2:Block) 
WHERE g.game_id='G222' and u.email_id = '[email protected]' 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 

In questa query v'è una dichiarazione merge all'interno del WHEN 'y' THEN, questa query genera un errore:

Invalid input ']': expected whitespace or a relationship pattern (line 7, column 82) "MERGE (u)-[r2:STAGE {startdate:20141225, enddate:'99999999', status:'InProgress'}]->(b2 {fork:'fail'}) RETURN 1"

Fondamentalmente sto cercando di creare un rapporto basato su una proprietà cioè un MERGE all'interno di una dichiarazione CASE, ho provato diversi modi per farlo funzionare come fare un ritorno in quel caso quando restituisce qualche valore ecc. ma nulla ha funzionato finora.

Quale potrebbe essere il problema con questa query?

risposta

11

Per eseguire operazioni di scrittura condizionale è necessario utilizzare il trucco FOREACH. Usando CASE si restituisce un array di un elemento o uno vuoto. FOREACH itera sopra l'espressione CASE e quindi esegue l'azione condizionatamente. Se si desidera una parte ELSE, è necessario disporre di un'altra FOREACH utilizzando la condizione inversa nello CASE. Come esempio, invece di

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 

uso

FOREACH(ignoreMe IN CASE WHEN 'y' THEN [1] ELSE [] END | 
    MERGE (u)-[r2:STAGE {startdate:20141225, enddate:'99999999', status:'InProgress'}]->(b2 {fork:'fail'}) 
) 
FOREACH(ignoreMe IN CASE WHEN NOT 'y' THEN [1] ELSE [] END | 
    MERGE (u)-[r2:STAGE {startdate:20141225, enddate:'99999999', status:'InProgress'}]->(b2) 
) 

Vedi anche Mark's blog post su questo.

+0

Grazie Stefan, sì, hai ragione, a quanto pare abbiamo bisogno di usare foreach, ho anche fatto riferimento ad uno dei vostri primi messaggi in StackOverflow, la logica è infine così CON U, b2, b1, g, r1, CASE WHEN (b1.fork = 'y' e b2.fork = 'success') o (b1.fork = 'n') o (b1. fork = 'success') THEN ['ok'] ELSE [] END come array1 FOREACH (el1 in array1 | MERGE (u) - [r2: STAGE {startdate: 20141225, enddate: 99999999, stato: 'InProgress'}] -> (b2)) – deepesh

+0

Bel trucco, ma puoi spiegare qual è il significato di 'THEN [1] ELSE []', e cos'è 'ignoreMe' * (mi dispiace, non potrei ignorarti) *? – ADTC

+0

leggi il post sul blog di Mark linkato sopra. –

2

risolto il problema come sotto

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)) 

cioè CASO utilizzato Quando creare una matrice fittizio che in un modo ha elementi fittizi corrispondenti alla conto delle corrispondenze e quindi utilizzare foreach per scorrere il risultato.

Ancora una volta, grazie Stefan per l'idea ...

Deepesh

Problemi correlati