Cypher 查询中的多个 MATCH 子句和逗号有啥区别?
Posted
技术标签:
【中文标题】Cypher 查询中的多个 MATCH 子句和逗号有啥区别?【英文标题】:What is the difference between multiple MATCH clauses and a comma in a Cypher query?Cypher 查询中的多个 MATCH 子句和逗号有什么区别? 【发布时间】:2015-09-23 14:47:38 【问题描述】:在 Neo4j 的 Cypher 查询语言中,一个 MATCH 子句紧跟另一个如下有什么区别:
MATCH (d:Documentdocument_ID:2)
MATCH (d)--(s:Sentence)
RETURN d,s
与同一 MATCH 子句中的逗号分隔模式相比?例如:
MATCH (d:Documentdocument_ID:2),(d)--(s:Sentence)
RETURN d,s
在这个简单的例子中,结果是一样的。但是有什么“陷阱”吗?
【问题讨论】:
【参考方案1】:有一个区别:逗号分隔的匹配实际上被认为是同一模式的一部分。因此,例如,这里支持每个关系在结果路径中只出现一次的保证。
单独的 MATCH 是单独的操作,其路径不形成单一模式并且没有这些保证。
【讨论】:
【参考方案2】:我认为最好在有差异时提供一个示例来进行解释。 假设我们有官方 Neo4j 教程提供的“Movie”数据库。 :Person 和 :Movie 节点之间总共有 10 个 :WROTE 关系
MATCH (:Person)-[r:WROTE]->(:Movie) RETURN count(r); // returns 10
1) 让我们尝试下一个带有两个 MATCH 子句的查询:
MATCH (p:Person)-[:WROTE]->(m:Movie) MATCH (p2:Person)-[:WROTE]->(m2:Movie)
RETURN p.name, m.title, p2.name, m2.title;
您肯定会在结果中看到 10*10 = 100 条记录。
2) 让我们尝试使用一个 MATCH 子句和两种模式的查询:
MATCH (p:Person)-[:WROTE]->(m:Movie), (p2:Person)-[:WROTE]->(m2:Movie)
RETURN p.name, m.title, p2.name, m2.title;
现在您将看到返回 90 条记录。 这是因为在这种情况下,p = p2 和 m = m2 具有相同关系(:WROTE)的记录被排除。
比如第一种情况下有一条记录(两个MATCH子句)
p.name m.title p2.name m2.title
“亚伦·索尔金”“几个好男人”“亚伦·索尔金”“几个好男人”
虽然在第二种情况下没有这样的记录(一个 MATCH,两个模式)
【讨论】:
【参考方案3】:这些条款之间没有区别只要条款不相互链接。
如果你这样做了:
MATCH (a:Thing), (b:Thing) RETURN a, b;
同理:
MATCH (a:Thing) MATCH (b:Thing) RETURN a, b;
因为(也只是因为)a
和 b
是独立的。如果a
和b
通过关系链接,那么查询的含义可能会改变。
【讨论】:
【参考方案4】:以更通用的方式,“不能在同一结果记录中多次返回同一关系。”[参见1.5. Cypher Result Uniqueness in the Cypher manual]
MATCH-after-MATCH 和带有逗号分隔模式的单个 MATCH 都应在逻辑上返回笛卡尔积。除了逗号分隔的模式,我们必须排除那些我们已经添加了关系的记录。
在安迪的回答中,这就是为什么我们在第二种情况下排除了同一部电影的重复:因为每个 MATCH 的第二个表达式在那里使用与第一个表达式相同的 :WROTE 关系。
【讨论】:
【参考方案5】:如果查询的一部分包含多个不连贯的模式,这将在所有这些部分之间构建一个笛卡尔积。这可能会产生大量数据并减慢查询处理速度。虽然偶尔是有意的,但通常可以通过在不同部分之间添加关系或使用 OPTIONAL MATCH (identifier is: (a)) 来重新制定避免使用此叉积的查询。 简而言之,它们在这两个查询中没有区别,但非常小心地使用它。
【讨论】:
【参考方案6】:以更通用的方式,“在同一结果记录中,不能多次返回同一关系。” [见 1.5。 Cypher 手册中的 Cypher 结果唯一性]
这个说法怎么样?
MATCH p1=(v:player)-[e1]->(n)
MATCH p2=(n:team)<-[e2]-(m)
WHERE e1=e2
RETURN e1,e2,p1,p2
【讨论】:
以上是关于Cypher 查询中的多个 MATCH 子句和逗号有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
Cypher:使用 WHERE 子句或 MATCH 属性定义进行精确匹配?