在neo4j中获取叶子的第一根

时间:2017-05-04 12:03:47

标签: neo4j cypher

我有简单的图表:

CREATE (:leaf)<-[:rel]-(:nonleaf)<-[:rel]-(:nonleaf)<-[:rel]-(:nonleaf)<-[:rel]-(r1:nonleaf{root:true})<-[:rel]-(r2:nonleaf{root:true})

我希望第一个祖先从(:leaf)开始设置root:true。那是我想获得r1。为此我写了下面的密码:

MATCH (:leaf)<-[*]-(m)<-[*]-(r:nonleaf{root:true}) WHERE m.root<>true OR NOT exists(m.root) 
RETURN r

但它返回了(r1)(r2)。跟随密码发生了同样的事情:

MATCH shortestPath((l:leaf)<-[*]-(r:nonleaf{root:true}))
RETURN r

这是怎么回事?

更新
好好思考后,我点击了我的想法,(r2)也会被返回,因为在从(:leaf)(r2)的路径上,有些节点没有设置root属性(这应该早点点击我,非常明显,微妙的解释错误)。换句话说,如果&#34;至少有一个(:nonleaf{root:true})&#34; 以下条件为真,则返回mm.root<>true OR NOT exists(m.root)。这里的要求是条件应该对路径上的&#34;所有m s&#34; 有效,&#34;不是至少一个{{1 }}&#34; 即可。现在仍然需要弄清楚如何把它放在密码中,而我对cypher的控制并不紧张......

2 个答案:

答案 0 :(得分:1)

您可以借助single()谓词函数强制匹配路径上有一个根节点:

MATCH p=(:leaf)<-[*]-(r:nonleaf{root:true})
WHERE SINGLE(m IN nodes(p) WHERE exists(m.root) AND m.root=true )
RETURN r

答案 1 :(得分:1)

你只需稍微调整你的where条件就可以说&#34;并且匹配的根:nonleaf节点之前的:nonleaf节点本身不被标记为根节点&#34; 。我认为这将满足您的需求。

MATCH (l:leaf)<-[*]-(r:nonleaf {root: true})
WHERE NOT (:nonleaf {root: true})<--(r)
RETURN r

<强>已更新

阅读评论中的更新示例,我想到了另一种使用APOC程序解决问题的方法apoc.path.expandConfig

确实需要对您的数据进行细微更改。每个root: true节点都应在其上设置:root标签。这是更新声明......

MATCH (n:nonleaf {root:true})
SET n:root
RETURN n

这是更新的查询

MATCH (leaf:leaf {name: 'leaf'})
WITH leaf
CALL apoc.path.expandConfig(leaf, {relationshipFilter:'<rel',labelFilter:'/root'} ) yield path
RETURN last(nodes(path))