Cypher查询中的逗号有什么作用?

时间:2015-12-04 13:40:25

标签: neo4j cypher

一位同事编写了类似这样的内容:

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

逗号有什么作用?它只是MATCH的简写吗?

2 个答案:

答案 0 :(得分:16)

由于Cypher的ASCII艺术语法只允许您在一行中指定一个线性连接链,因此逗号至少部分地允许您指定可能分支的内容。例如:

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

表示三个节点都连接到b(两个传入关系和一个传出关系。

如果匹配得太长,逗号对于分隔行也很有用,如下所示:

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

显然,这不是一个很长的路线,但它相当于:

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

但一般来说,任何MATCH语句都指定了您要搜索的模式。 MATCH的所有部分构成了模式。在您的情况下,您实际上正在寻找两个未连接的模式((a)-[r]->(b)(c)),因此Neo4j将找到两种模式的每个实例的每个组合,这可能非常昂贵。在Neo4j 2.3中,您也可能会收到一条警告,告知这是一个可以为您提供笛卡尔积的查询。

但是,如果指定多个匹配项,则需要搜索不同的模式。所以,如果你这样做了:

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

从概念上讲,我认为它有点不同,但结果是一样的。但我知道它与OPTIONAL MATCH完全不同。如果你这样做了:

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

您只能找到Foo个节点未连接或连接到BarBaz节点的实例。如果你这样做:

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

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

修改

在评论中,Stefan Armbruster指出,逗号也可用于将子模式分配给个人标识符。如:

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

谢谢Stefan!

EDIT2:另见Mats&#39;回答如下

答案 1 :(得分:10)

Brian很好地解释了如何使用逗号来构建更大的子图模式,但是使用逗号和第二个MATCH子句之间也存在微妙但重要的区别。

考虑两个节点的简单图,它们之间有一个关系。查询

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

将返回带有数字1的一行。但是,用逗号替换第二个MATCH,并且根本不会返回任何行:

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

这是因为关系唯一性的概念。在每个MATCH子句中,每个关系只会遍历一次。这意味着对于我的第二个查询,图中的一个关系将与第一个模式匹配,第二个模式将无法匹配任何内容,导致整个模式不匹配。我的第一个查询将匹配每个子句中的一个关系,从而为结果创建一行。

在Neo4j手册中了解更多相关信息:http://neo4j.com/docs/stable/cypherdoc-uniqueness.html