Conditional flow of query for running/skipping code blocks

Hello team.
I'm using Amazon Neptune with openCypher. Testing queries in Jupyter Notebooks before they're implemented in my app to call an AWS Lambda for submitting queries to the Neptune DB.

I am writing queries but ran into a principal issue: how can I conditionally run or skip certain code blocks in the query, all the way through the final RETURN statement?

The intuitive solution would be using WHERE before a code block, however, when the where clause is false - the query flow terminates and no subsequent code blocks are processed.

Consider the following pseudo-structure, assuming some $params are passed to the query:

...
WITH a, b, c WHERE $code=1 OR $code=2
...do something
WITH a, b, c WHERE $code=1 OR $code=3
...do something else
With a
RETURN a

Or the following structure:

...
WITH a, b, c WHERE $unlinkFirst=true
...detach delete some nodes
WITH a, b, c
...create a new node
RETURN something

Can you please advise, what is the proper way to achieve this in openCypher?

Thanks!

There are several things I can suggest.

  1. If you want to conditionally mutate something and not return a value, a call subquery is very effective. Example:

Call {
With n
With n
Where n is not null
Create (n)
}

  1. You can use apoc procedures apoc.do (read only), apoc.do.when (for writes)
  1. ForEach approach: some people like this, but I don’t. It looks awkward and it is constrained by the limits of the forEach loop, I.e you can’t match. The case statement creates a list with one element or zero elements based on the predicate, so the forEach will run once or not at all.

ForEach (
Case when insert_predicate then [1] else end |
Insert cypher statements
)

Hey Gary, many thanks for your detailed answer.
I tried all of these in Jupyter Notebook - none of these are supported.
I wonder, could these not be supported in openQuery?
For example, ForEach is not even mentioned in the openCypher v9 reference manual I'm using.
It seem no apoc library is available at all.

I also tried sending CALL {MATCH (p) RETURN p} directly from my app (not using Jupyter Notebook) and received an error as well.

See my results:

Query1:

%%oc
CALL {
    MATCH (p)
    RETURN p
}

Error:

{
  "detailedMessage": "Invalid input '{': expected whitespace, comment, namespace of a procedure or a procedure name (line 1, column 6 (offset: 5))",
  "requestId": "46308c09-9e21-4f4f-bc1b-a83c57cae402",
  "code": "MalformedQueryException"
}

Query2:

%%oc
CALL apoc.do.when(true,
  'CREATE (a:Node{name:"A"}) RETURN a AS node',
  'CREATE (b:Node{name:"B"}) RETURN b AS node',
  {}
)
YIELD value
RETURN value.node AS node;

Error:

{
  "detailedMessage": "CALL clause",
  "requestId": "847ac171-ff2f-48d3-9826-d92bc91a2151",
  "code": "UnsupportedOperationException"
}

Query3:

%%oc
RETURN apoc.version() AS output

Error:

{
  "detailedMessage": "Unknown function: 'version'",
  "requestId": "4e4ea023-a639-4e3c-a5ba-ea9168ed85ce",
  "code": "MalformedQueryException"
}

Query4:

%%oc
ForEach (
Case when true then [1] else [0] end |
MATCH (p) RETURN p
)

Error:

{
  "detailedMessage": "Invalid input 'w': expected whitespace, comment or IN (line 2, column 6 (offset: 15))",
  "requestId": "e2d11594-d0f4-4440-b896-80d8927bafee",
  "code": "MalformedQueryException"
}

Am I doomed?
Thank you!

Apoc is a library that runs on the server, it will not be available using Neptune.

I don’t know if the other clauses are neo4j specific. They don’t seem to work for you.

I guess I'll have to improvise some workarounds such as splitting into multiple queries called in a chain from the app. I don't like it (as it breaks the transaction), but that's what I have at the moment.

Thank you Gary. I appreciate your support on this!

If you were using the neo4j drivers, you could execute multiple queries using the same transaction using a transaction function.

Sorry, I have not used Neptune.

Your welcome...glad to help anytime.

1 Like