Cypher: which parts of a template can be bound to a variable?
I can get all the nodes User
like this:
MATCH (n:User)
RETURN n
In this case it is n
bound to node. But let's say I want to write a Cypher query that gets a property of name
each labeled node User
and a property with a key name
and returns that as username
. I write:
MATCH (n:User { name: username })
RETURN username
But it seems impossible: the Cypher parser does not accept an ID username
at this point in the template. Is there any other way to do this? What positions of the template can the identifier be placed in? Just knots and relationships?
(Yes, I know I can bind to a node, check if a property exists name
, and if this retrieves that value. But it would be more elegant to directly match the pattern on the property.)
source to share
To answer the question posed in the title:
Within a sentence, MATCH
specific paths, nodes, and relationships can be bound to identifiers:
MATCH p = (n)-[r]-(m)
After a sentence MATCH
combined with a sentence, WITH
everything can be tied to an ID:
MATCH p = (n)-[r]-(m)
WITH n.name AS identifier
or
MATCH p = (n)-[r]-(m)
WITH COUNT(r) AS some_identifier
or
MATCH p = (n)-[r]-(m)
WITH EXTRACT(x IN NODES(p) | x.name) AS another_identifier
and etc.
Use WITH
when you want to bind anything other than a path, node, or relation to an id. Your specific example seems to demonstrate a misunderstanding of the role of curly braces in a sentence MATCH
. They are there for what I like to call " WHERE
air conditioning cuts ." Curly braces allow you to set node and relation properties in a sentence MATCH
instead of conditioning in the next sentence WHERE
.
MATCH (n:User {name:"Alice"})
RETURN n
and
MATCH (n:User)
WHERE n.name = "Alice"
RETURN n
are identical. This is a matter of convenience / preference.
TL; DR - No, you cannot bind a property name
to an identifier username
in a sentence MATCH
. Use WITH n.name AS username
for this.
source to share
You can return properties of node easily
MATCH (n:User)
RETURN n.name
you can access these properties in any expression
MATCH (n:User)
WHERE n.name = "John"
RETURN n.name
if you want to assign this property to an indefigure you can do it with WITH
MATCH (n:User)
WITH n.name as userName
RETURN userName
source to share
Edit - Actual Answer
As far as binding a variable to consistent properties, this is not possible. As you say, binding only applies to nodes and relationships. You can also name values ββin statements Return
and sentences With
.
It's important to note that the values ββin parentheses are used to select nodes (for example, the WHERE clause), but only work on exact matches. I'm not sure if there is any roadmap element to allow pattern matching within brackets, making this valid:
MATCH (n:User{name:"Jam.*"})
RETURN n
In previous iterations of Neo (and you can still if you want), you can use START semantics to do index matches based on the Lucene index, but that would not have allowed the property to bind either.
However, you do not need to check for the existence of the property, as the missing property will not match. As you correctly understood, your only option is:
MATCH (n:User)
WHERE n.name =~ "James.*"
RETURN n.name AS username
Or for a non-regex:
MATCH (n:User{name:"James"})
RETURN n.name AS username
Original answer
Of course if you want to match all users and return a list of values.
MATCH (n:User)
RETURN n.name AS username
Or a single value that contains an array of usernames:
MATCH (n:User)
RETURN COLLECT(n.name) AS usernames
Or, if you want to match a specific user:
MATCH (n:User{propToMatch:"valToMatch"})
RETURN n.name AS username
The values ββin the MATCH in parentheses are used as a WHERE clause, not as a return value.
source to share
No, it is not possible to bind a property value to an identifier in a template. The only things that can be associated with IDs in a template are nodes and relationships.
The only way to achieve the same request is to manually check for the presence of the property key in node and retrieve the property value if the key exists, e.g .:
MATCH (n:User)
WHERE HAS (n.name)
RETURN n.name AS username
source to share