使用 Cypher 仅匹配 Neo4J 中的完整路径(不是子路径)
Match Only Full Paths in Neo4J with Cypher (not sub-paths)
如果我有如下图(嵌套可以针对任意数量的节点进行):
(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)
?查询也应该是能够 return 没有给定类型关系的节点。
到目前为止我只是在做以下事情(我只想要 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}}}}}
是否可以直接用查询生成地图?
这是一个可以帮助您入门的查询。当存在没有分叉的单链时,此查询将 return 只是最长的节点链。它与您的路径一样匹配所有路径,但通过使用 limit 来减少结果,只有 return 是最长的路径。
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
我认为这就是你问题的第二部分,其中有多个路径。它查找最后一个节点没有 outbound :KNOWS
关系并且起始节点没有 inbound :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)])
只需要做类似的事情,这对你的例子有效,找到所有没有传出的节点 [: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
如果我有如下图(嵌套可以针对任意数量的节点进行):
(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)
?查询也应该是能够 return 没有给定类型关系的节点。
到目前为止我只是在做以下事情(我只想要 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}}}}}
是否可以直接用查询生成地图?
这是一个可以帮助您入门的查询。当存在没有分叉的单链时,此查询将 return 只是最长的节点链。它与您的路径一样匹配所有路径,但通过使用 limit 来减少结果,只有 return 是最长的路径。
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
我认为这就是你问题的第二部分,其中有多个路径。它查找最后一个节点没有 outbound :KNOWS
关系并且起始节点没有 inbound :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)])
只需要做类似的事情,这对你的例子有效,找到所有没有传出的节点 [: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