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.
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).
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.
Your last cypher may work but its still going to do a AllNodesScan. If your graph has 100million nodes but only 30k nodes with label facebook your query will still examine all 100million nodes so as to find the 30k facebook nodes.
As @cobra indicated
I had the same question earlier this week, in the doc , it says it is not possible to use parameters for labels.
and this is so since the cypher planner would not now how to necessarily plan the query if a label was defined via a parameter
Try this:
with ["facebook"] as lbl
MATCH p = (a)-[]-(b)
where labels(a) = labels(b) = lbl
with nodes(p)as n1, relationships(p) as rels
return n1, rels limit 22