Cypher 查询中的逗号有什么作用? [英] What does a comma in a Cypher query do?

查看:17
本文介绍了Cypher 查询中的逗号有什么作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一位同事的代码如下:

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 节点不连接任何东西,或者同时连接到 BarBaz 节点的实例.而如果你这样做:

MATCH (a:Foo)可选匹配 (a)-->(b:Bar)可选匹配 (a)-->(c:Baz)

您将找到每个 Foo 节点,并且您将独立匹配零个或多个连接的 BarBaz 节点.

在评论中 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆