1

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

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

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

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

所以主要问题是当我做一些事情时:

  1. 匹配 a-->b, a-->c, a-->d
  2. 匹配 a-->b-->c-->d

Cypher 不保证(当我尝试时)a、b、c 和 d 都是不同的节点。对于小图,这可以很容易地修复

WHERE not(a=b) AND not(a=c) AND ...

但我正在尝试制作大小为 10+ 的图表,因此检查所有节点之间的相等性不是一个可行的选择。Afaik,RETURN DISTINCT 效果不佳,因为它不检查变量之间的相等性,只检查不同行。有什么简单的方法可以指定查询以使不同命名的节点不同吗?

4

1 回答 1

0

老问题,但请查看APOC Path Expander 程序以了解如何解决这些类型的用例,因为您可以更改扩展的遍历唯一性行为(与使用遍历 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

对于标签和关系过滤,或基于预匹配节点列表的过滤(白名单、黑名单、endnode、终止节点),存在更丰富的选项。

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

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

于 2019-03-29T17:02:54.917 回答