Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
718 views
in Technique[技术] by (71.8m points)

neo4j - What does a comma in a Cypher query do?

A co-worker coded something like this:

match (a)-[r]->(b), (c) set c.x=y

What does the comma do? Is it just shorthand for MATCH?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...