在Neo4J中使用重复的方向关系模式查找N个级别的路径

时间:2015-05-20 17:47:16

标签: graph neo4j cypher family-tree

我试图使用Neo4j来分析家谱中的关系。我已经这样建模:

(p1:Person)-[:CHILD]->(f:Family)<-[:FATHER|MOTHER]-(p2)

我知道我可以遗漏家庭标签,只是让孩子与每位家长联系,但这对我的目的来说并不实用。这是我的图表的一个示例,黑线是我希望它生成的路径:

Full tree

我可以用

查询它

MATCH p=(n {personID:3})-[:CHILD]->()<-[:FATHER|MOTHER]-()-[:CHILD]->()<-[:FATHER|MOTHER]-()-[:CHILD]->()<-[:FATHER|MOTHER]-() RETURN p

但是关系的重复模式。我可以这样做:

MATCH p=(n {personID:3})(-[:CHILD]->()<-[:FATHER|MOTHER]-())* RETURN p

其中*表示重复:CHILD然后:FATHER | MOTHER关系,方向不同?显然,如果关系是相同的方向,我可以使用

-[:CHILD|FATHER|MOTHER*]->

我希望能够从人物#3一直查询到图表的顶部,如谱系图表,但也要具体说明需要多少级别(如3代,而不是结束时) -line)。

我遇到的另一个问题是,如果我不对-[:CHILD|FATHER|MOTHER*]-之类的关系发表指示,那么它将从第3个人开始,然后朝着我的方向前进想要(交替的箭头),但也要沿着链条下降找到所有其他的兄弟,阿姨,叔叔等等。&#34;。

任何经验丰富的Cypher专家都会帮助我吗?

4 个答案:

答案 0 :(得分:2)

我只是在同一个问题上。而且我发现APOC Expand path procedures只是在完成您/我们想要的。

在您的示例中,您可以使用apoc.path.subgraphNodes来获取Person#3的所有祖先:

MATCH (p1:Person {personId:3})
CALL apoc.path.subgraphNodes(p1, {
    sequence: '>Person,CHILD>,Family,<MOTHER|<FATHER'
}) YIELD node
RETURN node

或者,如果您只希望始祖人最多3代的祖先,则将maxLevel: 6添加到配置中(因为1代是由2个关系定义的,所以3代是6个级别):

MATCH (p1:Person {personId:3})
CALL apoc.path.subgraphNodes(p1, {
    sequence: '>Person,CHILD>,Family,<MOTHER|<FATHER',
    maxLevel: 6
}) YIELD node
RETURN node

如果您只希望第三代的祖先,也就是只曾祖父母,也可以指定minLevel(使用apoc.path.expandConfig):

MATCH (p1:Person {personId:3})
CALL apoc.path.expandConfig(p1, {
    sequence: '>Person,CHILD>,Family,<MOTHER|<FATHER',
    minLevel: 6,
    maxLevel: 6
}) YIELD path
WITH last(nodes(path)) AS person
RETURN person

答案 1 :(得分:1)

您可以撤消模型中CHILD关系的方向性,如:

(p1:Person)<-[:CHILD]-(f:Family)<-[:FATHER|MOTHER]-(p2)

这样,您可以在查询中使用简单的-[:CHILD|FATHER|MOTHER*]->模式。

反转方向性实际上也是直观的,因为您可以更自然地将图形可视化为家谱,所有箭头都向下流动&#34;向下&#34;从祖先到后代。

答案 2 :(得分:0)

是的,这是一个有趣的案例。我非常肯定(虽然我可以纠正)这是不可能的。你有可能拥有并维持两者吗?您可以使用简单的密码查询创建额外的关系:

MATCH (parent)-[:MOTHER|FATHER]->()<-[:CHILD]-(child)
CREATE (child)-[:CHILD_OF]->parent

答案 3 :(得分:0)

好的,所以这是一个想法:

MATCH path=(child:Person {personID: 3})-[:CHILD|FATHER|MOTHER*]-(ancestor:Person),
WHERE ancestor-[:MOTHER|FATHER]->()
RETURN path

通常我会在MATCH中使用第二个条款,如下所示:

MATCH
  path=(child:Person {personID: 3})-[:CHILD|FATHER|MOTHER*]-(ancestor:Person),
  ancestor-[:MOTHER|FATHER]->()
RETURN path

但Neo4j(至少默认情况下,我认为)并没有穿过这条路。也许逗号分离会很好,这将是一个问题:

MATCH path=(child:Person {personID: 3})-[:CHILD|FATHER|MOTHER]-(ancestor:Person)-[:MOTHER|FATHER]->()

我很想知道你发现了什么!