Reputation: 36395
I can get all User
nodes like this:
MATCH (n:User)
RETURN n
In this case, n
is bound to the node. But let's say I want to write a Cypher query which gets the name
property of every node with the label User
and a property with the key name
, and return this as username
. I write:
MATCH (n:User { name: username })
RETURN username
But this appears to not be possible: the Cypher parser does not accept the identifier username
in that location of the pattern. Is there another way to do it? What positions of a pattern is it possible to put an identifier? Just nodes and relationships?
(Yes, I'm aware I can bind to the node, check whether a name
property exists, and if so extract that value. But it would be more elegant to directly pattern match on the property.)
Upvotes: 3
Views: 1136
Reputation: 36395
No, it is not possible to bind a property value to an identifier in a pattern. The only things that can be bound to identifiers in a pattern are nodes and relationships.
The only way to achieve the same query is to manually check for the existence of the property key on the node and extract the property value if the key exists, like this:
MATCH (n:User)
WHERE HAS (n.name)
RETURN n.name AS username
Upvotes: 0
Reputation: 7790
To answer the question posed in the title:
Within the MATCH
clause specifically, paths, nodes, and relationships can be bound to identifiers:
MATCH p = (n)-[r]-(m)
After the MATCH
clause, in combination with the WITH
clause, anything can be bound to an identifier:
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
etc.
Use WITH
if you want to bind anything other than a path, node, or relationship to an identifier. Your specific example seems to showcase a misunderstanding of the role of the curly braces within a MATCH
clause. They are there for what I like to call "shorthand WHERE
conditioning." The curly braces allow you to condition on node and relationship properties within the MATCH
clause instead of conditioning in a subsequent WHERE
clause.
MATCH (n:User {name:"Alice"})
RETURN n
and
MATCH (n:User)
WHERE n.name = "Alice"
RETURN n
are identical. It is a matter of convenience / preference.
TL;DR - No, you can't bind the name
property to an identifier username
within a MATCH
clause. Use WITH n.name AS username
to do this.
Upvotes: 4
Reputation: 3739
Edit - Actual Answer
With regards to binding a variable to the matched properties this is not possible. Like you say the binding is only applicable to Nodes and Relationships. You can also name values in Return
statements and in With
clauses.
It is important to note that the values in parenthesis are used to select nodes (like a WHERE clause) but only work on exact matches. I'm not sure if there is any roadmap item for allowing pattern matching inside the parenthesis, making this valid:
MATCH (n:User{name:"Jam.*"})
RETURN n
In previous iterations of Neo (and you still can if you wish) you could use the START semantics to do index matches based on a Lucene Index, but that too would not have allowed property binding.
Still you do not need to test for the presence of the property as a missing property will not match anyway. As you correctly surmised your only option is:
MATCH (n:User)
WHERE n.name =~ "James.*"
RETURN n.name AS username
Or for 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 which 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
Values in the MATCH in parenthesis are used like a WHERE clause and not as the return value.
Upvotes: 0
Reputation: 41676
You can easily return properties of a node
MATCH (n:User)
RETURN n.name
you can access these properties in any expressions
MATCH (n:User)
WHERE n.name = "John"
RETURN n.name
if you want to assign this property to an indentifier you can do it with WITH
MATCH (n:User)
WITH n.name as userName
RETURN userName
Upvotes: 2