Having a label as a parameter in a cypher query (efficiently)

Hello all,

I am looking for a way to get a label as a string from my user AND use the label optimization in my query (rather than have the engine go for a full DB scan).

2 ways I have found so far of doing so (I'll use the WITH keyword to simulate user input):
1.

WITH "facebook" as company
MATCH p = (a:company)-->(b:company)
RETURN p

This one just won't work, as cypher apparently does not know how to handle form of (node_name:label_name) when label_name is a parameter.

WITH "facebook" as company
MATCH p = (a)-->(b)
WHERE ALL (x IN nodes(p) WHERE company IN labels(x))
RETURN p

This one works, but performs a full DB scan, not using the label optimization benefit for improved performance.

Any ideas?
Thanks!

It's not clear. Do you have a node with label "facebook"?

Yep (just an example for an input string representing a label).
I'm allowing myself to assume that the given string would always represent a valid label in my graph. (side note: I don't think that really matters - if label doesn't exist in graph and query is valid, it should still run successfully and just return 0 results).

Hello @roymaor1 :slight_smile:

I had the same question earlier this week, in the doc, it says it is not possible to use parameters for labels.

Your second solution is right:

WITH "facebook" as company
MATCH p = (a)-->(b)
WHERE ALL (x IN nodes(p) WHERE company IN labels(x))
RETURN p

But @andrew.bowman advised me to use the other option:

  • write the label in the language you use to encapsulate your request, for example Python
  • to sanitize what you are appending since this is a cypher injection risk (check that the string you will use is only a label and not something else)

Example:

label = "facebook"
query = "MATCH p = (a:"+label +")-->(b:"+label +") RETURN p"

Regards,
Cobra

3 Likes

That looks good @Cobra. Thanks alot

1 Like

I would add the following.

label = "facebook".Replace('`', '\'').Replace(';', '_')
query = "MATCH p = (a:`"+label +"`)-->(b:"+label +") RETURN p"

What we are doing here is we added backticks so even if the label contains illegal characters, they will be executed as string.

`label`

Then we disallow the use of the backtick and semicolon in the label. This should at least allow the script to fail if someone tries to perform injection as they cannot exit the backtick escape and cannot terminate properly resulting in a query the DB will reject.

It is not fail proof though. There will be someone who is smart that can go around this.