Neo4j 强制多路径查询中的关系顺序

Neo4j 强制多路径查询中的关系顺序,neo4j,cypher,Neo4j,Cypher,我将neo4j作为一个图形数据库进行研究,可变长度路径查询将是一个非常重要的用例。我现在认为我找到了一个Cypher不支持的示例查询 主要问题是,我想将组合关系视为单个关系。让我举个例子:寻找合作者。我使用标准的电影数据库完成了这项工作。目标是找到所有与汤姆·汉克斯搭档的演员。这可以通过查询找到: MATCH (tom {name: "Tom Hanks"})-[:ACTED_IN]->()<-[:ACTED_IN]-(a:Person) return a 然后很明显我们可以用 M

我将neo4j作为一个图形数据库进行研究,可变长度路径查询将是一个非常重要的用例。我现在认为我找到了一个Cypher不支持的示例查询

主要问题是,我想将组合关系视为单个关系。让我举个例子:寻找合作者。我使用标准的电影数据库完成了这项工作。目标是找到所有与汤姆·汉克斯搭档的演员。这可以通过查询找到:

MATCH (tom {name: "Tom Hanks"})-[:ACTED_IN]->()<-[:ACTED_IN]-(a:Person) return a
然后很明显我们可以用

MATCH (tom {name: "Tom Hanks"})-[:ACTED_IN*]-(a:Person) return a
值得注意的是,所有奇数长度路径都被排除在外,因为它们不以
结尾

现在,我发现了一个查询,我不知道如何进行递归:

MATCH (tom {name: "Tom Hanks"})-[:ACTED_IN]->()<-[:DIRECTED]-()-[:DIRECTED]->()<-[:ACTED_IN]-(a:Person) return DISTINCT a
然而,(除了看起来一点也不完整)。这也将抓住合作者。 也就是说,它将匹配表单的路径

()-[:ACTED_IN]->()<-[:ACTED_IN]-()

()-[:ACTED_IN]->()如果你想看到所有在导演汤姆·汉克斯(Tom Hanks)执导的电影中出演但从未与汤姆合作过的演员,这里有一种方法:

MATCH (tom {name: "Tom Hanks"})-[:ACTED_IN]->(m)
MATCH (m)<-[:ACTED_IN]-(ignoredActor)
WITH COLLECT(DISTINCT m) AS ignoredMovies, COLLECT(DISTINCT ignoredActor) AS ignoredActors
UNWIND ignoredMovies AS movie
MATCH (movie)<-[:DIRECTED]-()-[:DIRECTED]->(m2)
WHERE NOT m2 IN ignoredMovies
MATCH (m2)<-[:ACTED_IN]-(a:Person)
WHERE NOT a IN ignoredActors
RETURN DISTINCT a
MATCH(汤姆{name:“汤姆·汉克斯”})->(m)

MATCH(m)如果你想看到所有在汤姆·汉克斯导演的电影中出演的演员,但他们从未与汤姆合作过,这里有一种方法:

MATCH (tom {name: "Tom Hanks"})-[:ACTED_IN]->(m)
MATCH (m)<-[:ACTED_IN]-(ignoredActor)
WITH COLLECT(DISTINCT m) AS ignoredMovies, COLLECT(DISTINCT ignoredActor) AS ignoredActors
UNWIND ignoredMovies AS movie
MATCH (movie)<-[:DIRECTED]-()-[:DIRECTED]->(m2)
WHERE NOT m2 IN ignoredMovies
MATCH (m2)<-[:ACTED_IN]-(a:Person)
WHERE NOT a IN ignoredActors
RETURN DISTINCT a
MATCH(汤姆{name:“汤姆·汉克斯”})->(m)
MATCH(m)from在这里应该有所帮助,因为我们添加了表示标签、关系或两者的重复序列的功能

在这种情况下,由于您希望匹配模式的参与者而不是导演(或路径中的任何电影),因此我们需要指定要返回的路径中的哪些节点,这需要使用
labelFilter
以及
relationshipFilter
,或者只需使用组合的
序列
配置属性来指定预期的交替标签/关系,并确保在模式中所需的点处对:Person节点使用结束节点过滤器

以下是安装APOC后的操作方法:

MATCH (tom:Person {name: "Tom Hanks"})
CALL apoc.path.expandConfig(tom, {sequence:'>Person, ACTED_IN>, *, <DIRECTED, *, DIRECTED>, *, <ACTED_IN', maxLevel:12}) YIELD path
WITH last(nodes(path)) as person, min(length(path)) as distance
RETURN person.name
MATCH(tom:Person{name:“tom Hanks”})
调用apoc.path.expandConfig(tom,{sequence:'>Person,ACTED_IN>,*,*,config属性允许我们为序列中的每个步骤指定交替标签和关系类型筛选器,从起始节点开始。我们在第一人称标签(
>Person
)之前使用结束节点筛选器符号
)指示我们只希望在序列中的这一点上指向Person节点的路径(作为序列中的第一个元素,它在重复时也将是序列中的最后一个元素)。我们使用通配符
*
作为所有其他节点的标签过滤器,这意味着这些节点被列为白名单,无论其标签是什么,都将被遍历,但我们不想返回到这些节点的任何路径。

发件人在这里应该有所帮助,因为我们添加了表示标签、关系或两者重复序列的功能

在本例中,因为您希望匹配模式的演员而不是导演(或路径中的任何电影),我们需要指定要返回的路径中的哪些节点,这需要在
关系过滤器
之外使用
标签过滤器
,或者只使用组合的
序列
配置属性来指定预期的交替标签/关系,并确保在:P上使用结束节点过滤器在模式中所需的点处创建节点

以下是安装APOC后的操作方法:

MATCH (tom:Person {name: "Tom Hanks"})
CALL apoc.path.expandConfig(tom, {sequence:'>Person, ACTED_IN>, *, <DIRECTED, *, DIRECTED>, *, <ACTED_IN', maxLevel:12}) YIELD path
WITH last(nodes(path)) as person, min(length(path)) as distance
RETURN person.name
MATCH(tom:Person{name:“tom Hanks”})

调用apoc.path.expandConfig(tom,{sequence:'>Person,ACTED_IN>,*,*,config属性允许我们为序列中的每个步骤指定交替标签和关系类型筛选器,从起始节点开始。我们在第一人称标签(
>Person
)之前使用结束节点筛选器符号
)指示我们只希望在序列中的这一点上指向Person节点的路径(作为序列中的第一个元素,它在重复时也将是序列中的最后一个元素)。我们使用通配符
*
作为所有其他节点的标签过滤器,这意味着这些节点被列为白名单,无论它们的标签是什么,都将被遍历,但我们不想返回到这些节点的任何路径。

谢谢,这正是我所要寻找的。因此,澄清一下,这不能用纯密码表达,但需要APOC来完成正确捕获?正确,此时可变长度模式无法充分表达不同关系类型和/或节点标签的显式重复序列。您可以在扩展路径后使用Cypher筛选路径,但这可能非常昂贵,具体取决于筛选前可能的路径数。谢谢,这正是正确的我在寻找什么。因此,只是澄清一下,这不能用纯密码表达,但需要APOC来正确捕获?正确,此时可变长度模式不能充分表达不同关系类型和/或节点标签的显式重复序列。您可以在扩展路径后使用密码过滤路径,但根据筛选前可能的路径数,筛选可能非常昂贵。
MATCH (tom:Person {name: "Tom Hanks"})
CALL apoc.path.expandConfig(tom, {sequence:'>Person, ACTED_IN>, *, <DIRECTED, *, DIRECTED>, *, <ACTED_IN', maxLevel:12}) YIELD path
WITH last(nodes(path)) as person, min(length(path)) as distance
RETURN person.name