简体   繁体   English

如何在一个脱节的子图中获取所有节点 - neo4j / py2neo

[英]How to get all nodes in a disjointed sub-graph - neo4j / py2neo

If I have a neo4j database and I want to query to get all nodes that are in a one specific disjointed sub-graph. 如果我有一个neo4j数据库,我想查询以获取一个特定的脱节子图中的所有节点。 (in py2neo or in cypher) (在py2neo或cypher中)

If I have groups of nodes, the nodes in each group are connected by relationship within that group, but are not connects between groups. 如果我有节点组,则每个组中的节点按该组内的关系连接,但不在组之间连接。 Can I query for one node and get all the nodes in that node's group? 我可以查询一个节点并获取该节点组中的所有节点吗?

[UPDATED] [更新]

Original Answer 原始答案

If by "group of nodes" you mean a "disjoint subgraph", here is how you can get all the nodes in the disjoint subgraph (with relationships of any type) that contains a specific node (say, the Neo node): 如果通过“节点组”表示“不相交的子图”,则以下是如何获取包含特定节点(例如, Neo节点)的不相交子图(具有任何类型的关系)中的所有节点:

MATCH (n { name: "Neo" })
OPTIONAL MATCH p=(n)-[*]-(m)
RETURN REDUCE(s = [n], x IN COLLECT(NODES(p)) |
  REDUCE(t = s, y IN x | CASE WHEN y IN t THEN t ELSE t + y END )) AS nodes;

This query uses an OPTIONAL MATCH to find the nodes "related" to the Neo node, so that if that node has no relationships, the query would still be able to return a result. 此查询使用OPTIONAL MATCH查找与Neo节点“相关”的节点,因此如果该节点没有关系,则查询仍然可以返回结果。

The two (nested) REDUCE clauses make sure that the returned collection only has distinct nodes. 两个(嵌套的) REDUCE子句确保返回的集合只有不同的节点。

The outer REDUCE clause initialized the result collection with the n node, since it must always be in the disjoint subgraph, even if there are no other nodes. 外部REDUCE子句使用n节点初始化结果集合,因为它必须始终位于不相交的子图中,即使没有其他节点也是如此。

Better Answer 更好的答案

MATCH p=(n { name: "Neo" })-[r*0..]-(m)
WITH NODES(p) AS nodes
UNWIND nodes AS node
RETURN DISTINCT node

This simpler query (which returns node rows) uses [r*0..] to allow 0-length paths (ie, n does not need to have any relationships -- and m can be the same as n ). 这个更简单的查询(返回节点行)使用[r*0..]来允许0长度路径(即, n不需要任何关系 - 并且m可以与n相同)。 It uses UNWIND to turn the nodes node collection(s) into rows, and then uses DISTINCT to eliminate duplicates. 它使用UNWINDnodes节点集合转换为行,然后使用DISTINCT消除重复。

Alternate Solution (does not work yet, due to bug) 替代解决方案(由于错误,还没有工作)

This alternate solution below (which returns node rows) should also have worked, except that there is currently a bug ( that I just reported ) that causes all identifiers to be forgotten after a query unwinds a NULL (which can happen, for instance, if an OPTIONAL MATCH fails to find a match). 下面的这个替代解决方案(返回节点行)也应该有效,除了当前存在一个错误( 我刚刚报告 )导致在查询解除NULL之后忘记所有标识符(例如,如果OPTIONAL MATCH无法找到匹配)。 Due to this bug, if the Neo node has no relationships, the query below currently returns no results. 由于此错误,如果Neo节点没有关系,则下面的查询当前不返回任何结果。 Therefore, you have to use the query above until the bug is fixed. 因此,您必须使用上面的查询,直到修复错误。

MATCH (n { name: "Neo" })
OPTIONAL MATCH p=(n)-[*]-(m)
WITH n, NODES(p) AS nodes
UNWIND nodes AS node
RETURN DISTINCT (
  CASE
  WHEN node IS NULL THEN n
  ELSE node END ) AS res;

It might help if you added a diagram or some sample data. 如果您添加了图表或一些示例数据,它可能会有所帮助。 However, if I'm understanding your data model correctly you are defining "groups" of nodes as all nodes connected by a certain relationship? 但是,如果我正确理解您的数据模型,那么您将节点的“组”定义为通过某种关系连接的所有节点? So to get all members of "group1" nodes (let's define that as all nodes connected by a group1 relationship) and not any nodes connected to group2 you could use a query like this: 因此,要获取“group1”节点的所有成员(让我们将其定义为通过group1关系连接的所有节点)而不是任何连接到group2的节点,您可以使用如下查询:

MATCH (a:Person)-[:GROUP1]-(b:Person)
WHERE NOT exists((a)-[:GROUP2]-())
RETURN a

You can also use Node labels to define groups of Nodes. 您还可以使用节点标签来定义节点组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM