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


Brian does a good job of explaining how the comma can be used to construct larger subgraph patterns, but there's also a subtle yet important difference between using the comma and a second MATCH clause.

Consider the simple graph of two nodes with one relationship between them. The query

MATCH ()-->() MATCH ()-->() RETURN 1

will return one row with the number 1. Replace the second MATCH with a comma, however, and no rows will be returned at all:

MATCH ()-->(), ()-->() RETURN 1

This is because of the notion of relationship uniqueness. Inside each MATCH clause, each relationship will be traversed only once. That means that for my second query, the one relationship in the graph will be matched by the first pattern, and the second pattern will not be able to match anything, leading to the whole pattern not matching. My first query will match the one relationship once in each of the clauses, and thus create a row for the result.

Read more about this in the Neo4j manual: http://neo4j.com/docs/stable/cypherdoc-uniqueness.html