使用 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 nodes、edges 和 paths.
假设我在 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 nodes、edges 和 paths.