我试图使用Neo4j来分析家谱中的关系。我已经这样建模:
(p1:Person)-[:CHILD]->(f:Family)<-[:FATHER|MOTHER]-(p2)
我知道我可以遗漏家庭标签,只是让孩子与每位家长联系,但这对我的目的来说并不实用。这是我的图表的一个示例,黑线是我希望它生成的路径:
我可以用
查询它 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专家都会帮助我吗?
答案 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]->()
我很想知道你发现了什么!