我想找到从/到特定节点的所有路径。我希望路径中的每个节点只出现一次。
例如,在这样的图表中:
(a)-[:REL]->(b)-[:REL]->(c)-[:REL]->(a)
(a)-[:REL]->(e)-[:REL]->(f)-[:REL]->(a)
(e)-[:REL]->(b)
语法上:
e → b
↙ ↖ ↗ ↘
f → a ← c
密码:
CREATE (a { name:'A' })-[:REL]->(b {name:'B'})-[:REL]->(c { name:'C' })
-[:REL]->(a)-[:REL]->(e {name:'E'})-[:REL]->(f {name:'F'})-[:REL]->(a),
(e)-[:REL]->(b)
我希望从(a)开始的链研究返回
(a)->(b)->(c)->(a)
(a)->(e)->(f)->(a)
(a)->(e)->(b)->(c)->(a)
而从 (f) 开始只返回
(f)->(a)->(e)->(f)
并不是
(f)->(a)->(b)->(c)->(a)->(e)->(f)
因为它两次通过节点 (a)。
我试过:
MATCH p=(a {name:'F'})-[:REL*1..]->(a)
WHERE SINGLE(e1 IN TAIL(NODES(p)) WHERE SINGLE(e2 IN TAIL(NODES(p)) WHERE e1=e2))
RETURN p
但我没有结果。
我所能达到的最好的方法是不重复此查询的起始节点:
MATCH p=(a {name:'F'})-[:REL*1..]->(a)
WHERE SINGLE(e IN TAIL(NODES(p)) WHERE e=a)
RETURN p
但显然这不是我想要的,因为它也会返回
(f)->(a)->(b)->(c)->(a)->(e)->(f)
那是一条涉及节点 (a) 两次的路径。
有人可以建议我一个解决方案吗?
先感谢您。
附言我使用的 Neo4j 版本是 2.0
最佳答案
所以这里有一些模拟数据来复制你的例子:
$ create (a:T {label:"A"})-[:REL]->(b:T)-[:REL]->(c:T)-[:REL]->(a);
+-------------------+
| No data returned. |
+-------------------+
Nodes created: 3
Relationships created: 3
Properties set: 1
Labels added: 3
20 ms
neo4j-sh (?)$ match (a:T {label:"A"})
> CREATE a-[:REL]->(e:T)-[:REL]->(f:T)-[:REL]->(a);
+-------------------+
| No data returned. |
+-------------------+
Nodes created: 2
Relationships created: 3
Labels added: 2
27 ms
现在这是可以让您到达那里的查询(但它需要一些解释)。
match (a:T {label: "A"})-[:REL]->(somethingElse),
p=shortestPath((somethingElse)-[:REL*]->(a))
return p;
好的,所以基本上在我看来,您想要从 (a) 返回到自身的最短路径。但这很棘手,因为从节点到自身的最短路径始终是长度为 0 的空路径。因此,如果您执行类似
shortestPath((a)-[:REL*]->(a))
的操作结果将始终为空,这不是您想要的。所以相反,我匹配了一个
:REL
跳到下一个项目( somethingElse
),然后从该项目返回到 A 的最短路径。结果返回的路径 p
正是您想要的路径,只是它缺少来自 a-->somethingElse
的原始跃点.只要考虑到那个额外的跳数,那么a-->somethingElse
的组合与 p
应该是你正在寻找的答案。
关于neo4j - Cypher:如何找到不重复的单个节点的所有链?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26161974/