Search code examples
neo4jcypherneo4j-apoc

Pass variable to query used in a Neo4j apoc.do.case procedure


In this query I want to check the validity of the $accountId and $userId parameters, and if they are valid then create a new project attached to the User and Account nodes.

optional match (u:User {id:$userId})
optional match (a:Account {id:$accountId})
call apoc.do.case([
   not exists((u)-[:ACCOUNT_ADMIN]->(a)),
   "return {error:'user is not admin of the specified account'} as result",
   "match (u:User {id:$userId})-[:ACCOUNT_ADMIN]->(a:Account {id:$accountId})
      create (a)-[:CONTAINS]->(:Project {name:$projectName})<-[:PROJECT_ADMIN]-(u)
      return {result:'project created'} as result",
   {accountId:$accountId, userId:$userId, projectName:$projectName}
)
yield value
return value.result as result

It appears to work, but does not strike me as very elegant. What is particularly irksome is that in the else query passed to apoc.do.case I have to execute another match to relocate the nodes I've already located in the outer optional matches.

Is there no way to reuse the u and a variables that I've already located in the optional match's within the apoc.do.case else query?


Solution

  • Did you try this? Apart from the parameters, I think you should use apoc.do.when

    optional match (u:User {id:$userId})
    optional match (a:Account {id:$accountId})
    call apoc.do.when(
       not exists((u)-[:ACCOUNT_ADMIN]->(a)),
       "return {error:'user is not admin of the specified account'} as result",
       "with $a  AS a,$u AS u create (a)-[:CONTAINS]->(:Project {name:$projectName})<-[:PROJECT_ADMIN]-(u) return {result:'project created'} as result",
       {u:u,a:a, projectName:$projectName}
    )
    yield value
    return value.result as result