Neo4J中的完整路径与Cypher(不是子路径)匹配

时间:2015-01-22 02:05:31

标签: neo4j cypher

如果我有一个如下图形(其中嵌套可以继续任意数量的节点):

(a)-[:KNOWS]->(b)-[:KNOWS]->(c)-[:KNOWS]->(d)-[:KNOWS]->(e)
               |             |
               |            (i)-[:KNOWS]->(j)
               |
              (f)-[:KNOWS]->(g)-[:KNOWS]->(h)-[:KNOWS]->(n)
                             |
                            (k)-[:KNOWS]->(l)-[:KNOWS]->(m)

如何检索所有完整路径(在这种情况下,来自(a)-->(m)(a)-->(n) (a)-->(j)(a)-->(e)?查询还应该能够返回没有给定类型关系的节点。

到目前为止,我只是在执行以下操作(我只想要id属性):

MATCH path=(a)-[:KNOWS*]->(b)
RETURN collect(extract(n in nodes(path) | n.id)) as paths

我需要路径以便在编程语言中(在本例中为clojure)我可以创建一个这样的嵌套映射:

{"a" {"b" {"f" {"g" {"k" {"l" {"m" nil}}
                     "h" {"n" nil}}}
           "c" {"d" {"e" nil}
                "i" {"j" nil}}}}}

是否可以直接使用查询生成地图?

2 个答案:

答案 0 :(得分:1)

这是一个可以帮助您入门的查询。当存在没有分支的单个链时,此查询将仅返回最长的节点链。它匹配您所有的路径,但只返回最长的路径,使用limit来减少结果。

match p=(a:Node {name:'a'})-[:KNOWS*]->(:Node)
with length(p) as size, p
order by size desc
limit 1
return p as Longest_Path

我认为这会得到问题的第二部分,其中有多条路径。它会查找最后一个节点没有出站 :KNOWS关系的路径,以及起始节点没有入站 :KNOWS关系的路径。

match p=(a:Node {name:'a'})-[:KNOWS*]->(x:Node)
where not(x-[:KNOWS]->())
and not(()-[:KNOWS]->(a))
with length(p) as size, p
order by size desc
return reduce(node_ids = [], n in nodes(p) | node_ids + [id(n)])

答案 1 :(得分:0)

只需要做类似的事情,这适用于您的示例,找到所有没有传出[:KNOWS]的节点:

match p=(a:Node {name:'a'})-[:KNOWS*]->(b:Node)
optional match (b)-[v:KNOWS]->()
with p,v
where v IS NULL
return collect(extract(n in nodes(p) | n.id)) as paths