What does a comma in a Cypher query do?

Since Cypher’s ASCII-art syntax can only let you specify one linear chain of connections in a row, the comma is there, at least in part, to allow you to specify things that might branch off. For example:

MATCH (a)-->(b)<--(c), (b)-->(d)

That represents three nodes which are all connected to b (two incoming relationships, and one outgoing relationship.

The comma can also be useful for separating lines if your match gets too long, like so:

MATCH
  (a)-->(b)<--(c),
  (c)-->(d)

Obviously that’s not a very long line, but that’s equivalent to:

MATCH
  (a)-->(b)<--(c)-->(d)

But in general, any MATCH statement is specifying a pattern that you want to search for. All of the parts of that MATCH form the pattern. In your case you’re actually looking for two unconnected patterns ((a)-[r]->(b) and (c)) and so Neo4j will find every combination of each instance of both patterns, which could potentially be very expensive. In Neo4j 2.3 you’d also probably get a warning about this being a query which would give you a cartesian product.

If you specify multiple matches, however, you’re asking to search for different patterns. So if you did:

MATCH (a)-[r]->(b)
MATCH (c)

Conceptually I think it’s a bit different, but the result is the same. I know it’s definitely different with OPTIONAL MATCH, though. If you did:

MATCH (a:Foo)
OPTIONAL MATCH (a)-->(b:Bar), (a)-->(c:Baz)

You would only find instances where there is a Foo node connected to nothing, or connected to both a Bar and a Baz node. Whereas if you do this:

MATCH (a:Foo)
OPTIONAL MATCH (a)-->(b:Bar)
OPTIONAL MATCH (a)-->(c:Baz)

You’ll find every single Foo node, and you’ll match zero or more connected Bar and Baz nodes independently.

EDIT:

In the comments Stefan Armbruster made a good point that commas can also be used to assign subpatterns to individual identifiers. Such as in:

MATCH path1=(a)-[:REL1]->(b), path2=(b)<-[:REL2*..10]-(c)

Thanks Stefan!

EDIT2: Also see Mats’ answer below

Leave a Comment