一位同事编写了类似这样的内容:
match (a)-[r]->(b), (c) set c.x=y
逗号有什么作用?它只是MATCH的简写吗?
答案 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
个节点未连接或连接到Bar
和Baz
节点的实例。如果你这样做:
MATCH (a:Foo)
OPTIONAL MATCH (a)-->(b:Bar)
OPTIONAL MATCH (a)-->(c:Baz)
您将找到每个Foo
个节点,并且您将独立匹配零个或多个连接的Bar
和Baz
节点。
修改强>
在评论中,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