Cypher 查询中的逗号有什么作用? [英] What does a comma in a Cypher query do?
问题描述
一位同事的代码如下:
match (a)-[r]->(b), (c) set c.x=y
逗号有什么作用?它只是 MATCH 的简写吗?
由于 Cypher 的 ASCII-art 语法只能让您指定一行中的一个线性连接链,因此逗号至少部分地允许您指定可能分支的事物.例如:
MATCH (a)-->(b)<--(c), (b)-->(d)
表示三个节点都连接到b
(两个传入关系,一个传出关系.
如果匹配太长,逗号也可用于分隔行,如下所示:
匹配(a)-->(b)<--(c),(c)-->(d)
显然这不是很长的一行,但这相当于:
匹配(a)-->(b)<--(c)-->(d)
但一般来说,任何 MATCH
语句都指定了您要搜索的模式.MATCH
的所有部分构成了模式.在您的情况下,您实际上正在寻找两个未连接的模式((a)-[r]->(b)
和 (c)
),因此 Neo4j 会找到两种模式的每个实例的每种组合,这可能非常昂贵.在 Neo4j 2.3 中,您可能还会收到一条警告,指出这是一个会为您提供笛卡尔积的查询.
但是,如果您指定多个匹配项,则要求搜索不同的模式.所以如果你这样做了:
MATCH (a)-[r]->(b)匹配 (c)
概念上我觉得有点不同,但结果是一样的.不过,我知道 OPTIONAL MATCH
绝对不同.如果你这样做了:
MATCH (a:Foo)可选匹配 (a)-->(b:Bar), (a)-->(c:Baz)
您只会发现有一个 Foo
节点不连接任何东西,或者同时连接到 Bar
和 Baz
节点的实例.而如果你这样做:
MATCH (a:Foo)可选匹配 (a)-->(b:Bar)可选匹配 (a)-->(c:Baz)
您将找到每个 Foo
节点,并且您将独立匹配零个或多个连接的 Bar
和 Baz
节点.>
在评论中 Stefan Armbruster 提出了一个很好的观点,即逗号也可用于将子模式分配给单个标识符.例如:
MATCH path1=(a)-[:REL1]->(b), path2=(b)<-[:REL2*..10]-(c)
谢谢斯蒂芬!
另见下面垫子的回答
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?
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
这篇关于Cypher 查询中的逗号有什么作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!