知识库

如何比较两个图以确定它们是否相等

如果您想要比较两个图(或子图)以确定它们是否等效,以下 Cypher 将生成节点和属性的 md5sum 以进行比较。例如,您可能希望将测试/QA 实例与生产实例进行比较。

Neo4j 3.1 及更高版本

MATCH (n:Movie)
WITH n
ORDER BY n.title
WITH collect(properties(n)) AS propresult
RETURN apoc.util.md5(propresult);

3.1 之前的版本

MATCH (n:Movie)
WITH n
ORDER BY n.title
WITH collect(properties(n)) AS propresult
CALL apoc.util.md5(propresult) YIELD value AS md5_property
RETURN md5_property

当针对包含 38 个具有 Movie 标签的节点的默认 Movie 图运行时,这将返回

md5_property
3f8d4737d078783e12f7cf57a207dd67

上述 Cypher 需要安装 apoc 存储过程 集。

在上面的示例中,我们检查所有具有标签 :Movie 的节点,并生成这些节点所有属性的 md5sum,使用该总和来生成 md5sum 哈希.

为了获得正确的结果,我们需要按每个节点都定义且唯一的属性值对节点进行排序。因此,您可能希望使用一个定义为 属性存在约束唯一属性约束 的属性。

例如,如果 :Movie 节点具有多个具有相同 title 属性的节点,并且由于上面的 Cypher 按 n.title 排序,那么结果将按找到它们的顺序传递给 md5 存储过程。这通常基于节点创建的顺序。如果您有两个具有 title='The Matrix':Movie 节点,使用以下 Cypher 创建

CREATE (n:Movie {title:'The Matrix', genre:'Sci-Fi'})
CREATE (n1:Movie {title:'The Matrix', genre:'Action'})

那么只需运行 Cypher 生成 md5 哈希将生成一个 md5_property

md5_property
5bc18a680ef59ba09466da4217166d30

但是,如果您颠倒了 CREATE 语句的顺序,例如

CREATE (n1:Movie {title:'The Matrix', genre:'Action'})
CREATE (n:Movie {title:'The Matrix', genre:'Sci-Fi'})

相同 md5 哈希 Cypher 的结果将产生不同的 md5_property

md5_property
c3c565b45457d2182731050e0cbab221

在上面的示例中,为了获得正确的 md5 值,无论创建的顺序如何,我们都需要运行 Cypher,它将使用 ORDER BY 子句以保证的顺序返回数据

MATCH (n:Movie)
WITH n
ORDER BY n.name, n.genre
WITH collect(properties(n)) AS propresult
CALL apoc.util.md5(propresult) YIELD value AS md5_property
RETURN md5_property

这将始终返回

md5_property
c3c565b45457d2182731050e0cbab221
此外,我们不能简单地收集(n)(即整个节点),因为它在内部包含内部节点 ID(唯一的内部标识符)。

如果您在两个不同的环境中运行相同的 Cypher 并获得相同的 md5 总和,则可以证明节点在标签和属性定义方面是相同的。