使用 Cypher 从 Neo4j 图中提取子图

Extract subgraph from Neo4j graph with Cypher

假设我在 Neo4j 中有一个包含 5 个节点的集合,这样集合中的每个节点都至少连接到集合中的另一个节点。我想从 Neo4j 中提取由节点集合及其交互形成的子图。目前,我正在使用一种非常原始的方法,该方法涉及尝试找到从系统中的每个节点到每个其他节点的匹配项:

MATCH p=(n)-[]->(m)
WHERE id(n) IN [3,4,5,6,7] AND id(m) IN [3,4,5,6,7]
RETURN relationships(p);

但是,这个查询既冗余又低效;它必须遍历集合中节点的每个排列(例如,它将匹配节点#3 和#4,以及#4 和#3)。是否有更有效的方法来仅使用 Cypher 获取由这些节点形成的子图(无 Java)?

这是我所说的“子图”的一个例子:

我希望 Cypher return 所有标记为绿色的关系。请注意,集合中的节点不必与图中的其余部分隔离;它们仍然可以与图中的其他节点建立关系,但我希望 Cypher return 仅显示绿色的关系。

查询的这种修改有助于数组的冗余。

WITH [3,4,5,6,7] AS arr
MATCH p=(n)-[]->(m)
WHERE id(n) IN arr AND id(m) IN arr
RETURN relationships(p);

您可以使用节点标签或关系类型来区分(最终子图)和高效查询,但这取决于您的情况。

我想扩展 Richards 的回答,您也可以将其限制为 ID 位于不同组中的节点。

MATCH (n) WHERE id(n) IN [3,4,5,6,7]
MATCH p=(n)-->(m) 
WHERE id(n) < id(m) AND id(m) IN [3,4,5,6,7]
RETURN relationships(p);

结果

我开发了一个 python library/CLI cypher-subgraph 来重写和生成支持子图的 Cypher 查询。

该工具通过对节点和边添加 属性 来模拟子图功能。对于“x”子图中的每个节点和边,属性“__subgraph_x”将设置为真。

目前有“add-to”、“rewrite-for”、“删除”三个命令。

首先,你可以设置所有你想成为子图成员的节点和边,然后你可以在创建的子图中执行你想要的一切。

“add-to”命令改写了返回结果成为子图成员的查询

MATCH (v) RETURN v => MATCH (v) WITH v SET v.__subgraph_sg = true

“rewrite-for”命令重写了一个只在子图中执行的查询:

MATCH (v) RETURN v => MATCH (v { __subgraph_sg: true }) RETURN v

“删除”命令删除子图相关属性:

MATCH (v) OPTIONAL MATCH (v)-[e]-() REMOVE v.__subgraph_sg REMOVE e.__subgraph_sg

阅读查询没有已知的限制。所有命令都适用于 Cypher nodesedgespaths.