Neo4j:如何 return 为具有多重关系的每对节点创建一条路径

Neo4j: How to return a single path for each pair of nodes that have multiple relationships

假设这样的图表:

(感谢https://neo4j.com/blog/neo4j-2-0-ga-graphs-for-everyone/

(未显示但假设所有国家、所有艺术家和所有录音合同都在图中)

CYPHER 的用途是什么:

编辑:我尝试了 MATCH (c1:Country)-[]-(c2:Country)MATCH p=((c1:Country)-[]-(c2:Country))WITHUNWIND 的各种组合。我也尝试过使用 FOREACH 到 return 只有一条路径,但公式不太正确。

如果您使用子查询(Neo4j 4.1.x 或更高版本),这会更容易。这是因为子查询可以帮助将您需要执行的操作(在本例中为 collect())扩展到单个国家/地区的扩展和工作,而不必在整个查询的所有行中执行它,这可能会给堆带来压力。

实际上,由于国家/地区的数量很少,这不会成为问题,但在处理较大的节点集时,这是一种很好的方法。

MATCH (country:Country)
CALL {
 WITH country
 MATCH path = (country)<-[:FROM_AREA]-(:Artist)-[:RECORDING_CONTRACT]->(:Label)-[:FROM_AREA]->(other:Country)
 WHERE id(country) < id(other)
 RETURN other, collect(path)[0] as path
 LIMIT 20
}
RETURN country, path
LIMIT 20

让我们看看这是做什么的。 我们匹配到:国家节点。

在每个国家/地区,我们都会匹配您正在寻找的图案。如果这些是图中仅有的此类路径和标签,那么您可以省略模式中的标签,因为关系类型应该足以找到正确的节点。

这里的WHERE id(country) < id(other)是为了防止镜像结果。例如,在查询过程中,如果我们从 (United Kingdom)-[*]-(United States) 找到一条路径,并且我们还找到另一个方向的路径,对于 (United States)-[*]-(United Kingdom),您可能不希望 return两个都。所以我们对图表 ID 进行了限制,只有其中一个符合限制,镜像结果被过滤掉。

我们使用 RETURN other, collect(path)[0] as path 为每个国家和其他节点获取一条路径。请记住,这是在每个国家/地区节点调用的子查询中发生的,因此即使此处不存在 country,也会针对特定国家/地区节点执行此操作。

当我们聚合时(比如这个collect(path),分组键(通常是非聚合变量)变得不同,所以对于国家和另一个国家,这将收集它们之间的所有路径然后选择路径列表中的第一条,这样我们就得到了两个不同国家之间的单一路径。

我们将子查询结果限制为 20,因为我们总共知道我们不想要超过 20 条路径,所以每个国家/地区我们也不想要超过 20 条路径。对于这种情况,这可能有点多余,但是当查询更复杂时,这是确保您没有做超出需要的工作的正确方法。

我们在子查询之外还有另一个 LIMIT,这样如果只处理几个国家,每个国家有几条路径,总路径不会超过 20。