如何在Neo4j / Cypher查询中查找不同的节点

时间:2013-05-08 03:23:13

标签: neo4j cypher distinct-values

我正在尝试在neo4j / cypher中进行一些模式匹配,我遇到了这个问题:

我想搜索两种类型的图表:

  1. 星形图:具有一个中心节点和多个传出关系的图形。

  2. n长度线图:长度为n的线图,其中没有节点重复(我的图中有一些双向边和周期)

  3. 所以主要的问题是当我做的事情如下:

    1. 匹配a - > b,a - > c,a - > d
    2. 匹配a - > b - > c - > d
    3. Cypher不保证(当我尝试时)a,b,c和d都是不同的节点。对于小图,可以使用

      轻松修复

      中没有(a = b)而不是(a = c)AND ...

      但我正在尝试使用大小为10+的图形,因此检查所有节点之间的相等性不是一个可行的选择。 Afaik,RETURN DISTINCT不能正常工作,因为它不会检查变量之间的相等性,只能跨越不同的行。有没有简单的方法可以指定查询以使不同命名的节点不同?

1 个答案:

答案 0 :(得分:0)

古老的问题,但是请参考APOC Path Expander procedures,了解如何解决这类用例,因为您可以更改遍历唯一性行为以进行扩展(使用遍历API时可以采用相同的方式...这些程序使用)。

Cypher隐式使用RELATIONSHIP_PATH唯一性,这意味着每个返回的路径,一个关系必须是唯一的,不能在单个路径中多次使用。

虽然这对于需要所有可能路径的查询非常有用,但对于希望使用不同的节点或子图或防止在路径中重复节点的查询而言,它并不是一个很好的选择。

对于n长度的路径,假设深度6仅具有任何类型的传出关系,我们可以将唯一性更改为NODE_PATH,其中节点在每个路径上必须是唯一的,路径中不能重复:

MATCH (n)
WHERE id(n) = 12345
CALL apoc.path.expandConfig(n, {maxLevel:6, uniqueness:'NODE_PATH'}) YIELD path
RETURN path

如果希望所有可到达的节点达到一定深度(或通过省略maxLevel达到任何深度),则可以使用NODE_GLOBAL唯一性,或者仅使用apoc.path.subgraphNodes()

MATCH (n)
WHERE id(n) = 12345
CALL apoc.path.subgraphNodes(n, {maxLevel:6}) YIELD node
RETURN node

NODE_GLOBAL的唯一性意味着在所有路径上的节点必须是唯一的,它只会被访问一次,并且从给定的起始节点到该节点只有一条路径。这样可以大大减少需要评估的路径数量,但是由于这种行为,如果将所有关系扩展到已经访问过的节点,则不会遍历所有关系。

您不会通过此过程获得关系(您可以使用apoc.path.spanningTree(),尽管如前所述,并非所有关系都将包括在内,因为我们将仅捕获到每个节点的单个路径,而不是所有可能的路径节点的路径)。如果要使所有节点达到最大级别以及这些节点之间的所有可能关系,请使用apoc.path.subgraphAll()

MATCH (n)
WHERE id(n) = 12345
CALL apoc.path.subgraphAll(n, {maxLevel:6}) YIELD nodes, relationships
RETURN nodes, relationships

存在用于标签和关系过滤或基于预匹配节点列表的过滤(白名单,黑名单,端节点,终结者节点)的更多选项。

我们还支持重复关系或节点标签的顺序。

如果在扩展过程中需要按节点或关系属性进行过滤,那么这不是一个好选择,因为该功能尚受支持。