使用 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