简体   繁体   English

neo4j Cypher — 遍历可变长度路径,但在找到 label 时停止

[英]neo4j Cypher — traverse variable length path, but stop when a label is found

Suppose my graph database has a 'flow' of foo nodes.假设我的图形数据库有一个foo节点的“流”。 in between each foo nodes might be any number of bar , bar1 , bar2 , ... barN nodes which ultimately connect to the next foo node.在每个foo节点之间可能是任意数量的barbar1bar2 、 ... barN节点,它们最终连接到下一个foo节点。

So, all of these are possible所以,所有这些都是可能的

  • (a:foo)-->(:bar)-->(b:foo) (a:foo)-->(:bar)-->(b:foo)
  • (b:foo)-->(:bar)-->(c:foo)-->(:bar1)-->(d:foo) (b:foo)-->(:bar)-->(c:foo)-->(:bar1)-->(d:foo)
  • (a:foo)-->(:bar)-->(:bar1)-->(:bar2)-->(:barN)-->(c:foo) (a:foo)-->(:bar)-->(:bar1)-->(:bar2)-->(:barN)-->(c:foo)

etc.等等

I'd like to return each distinct pair of foo nodes which do NOT have any other foo nodes between them我想返回每对不同的foo节点,它们之间没有任何其他foo节点

For the above examples, the solution should return:对于上述示例,解决方案应返回:

  • a, b一,乙
  • b, c b、c
  • c, d c, d
  • a, c一、c

Solution should NOT include the following, which have foo nodes between them:解决方案不应包括以下内容,它们之间有 foo 节点:

  • b, d b, d
  • a, d广告

What I've tried.我试过的。 this returns all foo pairs that connect, regardless of what's in between.这将返回所有连接的 foo 对,无论它们之间是什么。

MATCH x=(a:foo)-[:RELTYPE*1..]->(b:foo)
RETURN a,b

This should work:这应该有效:

MATCH x = (a:foo)-[:RELTYPE*..]->(b:foo)
WHERE NONE(n IN NODES(x)[1..-1] WHERE ANY(l IN LABELS(n) WHERE l = 'foo'))
RETURN a, b

[UPDATE] [更新]

Or even better:甚至更好:

MATCH x = (a:foo)-[:RELTYPE*..]->(b:foo)
WHERE NONE(n IN NODES(x)[1..-1] WHERE n:foo)
RETURN a, b

You can also leverage APOC Procedures for path expansion procs which can handle this kind of use case.您还可以利用 APOC 程序来处理可以处理这种用例的路径扩展程序。

Using this graph:使用此图:

CREATE (a:foo {name:'a'}), (b:foo {name:'b'}), (c:foo {name:'c'}), (d:foo {name:'d'}), 
(a)-[:RELTYPE]->(:bar)-[:RELTYPE]->(b), 
(b)-[:RELTYPE]->(:bar)-[:RELTYPE]->(c)-[:RELTYPE]->(:bar1)-[:RELTYPE]->(d), 
(a)-[:RELTYPE]->(:bar)-[:RELTYPE]->(:bar1)-[:RELTYPE]->(:bar2)-[:RELTYPE]->(:barN)-[:RELTYPE]->(c)

We can apply this query:我们可以应用这个查询:

MATCH (start:foo)
CALL apoc.path.subgraphNodes(start, {relationshipFilter:'RELTYPE>', labelFilter:'/foo'}) YIELD node as end
RETURN start, end

This starts at every:foo node, traverses only outgoing:RELTYPE relationships, and will terminate expansion when reaching a:foo labeled node (the / before the 'foo' in the label filter indicates that this is a termination filter on the label).这从 every:foo 节点开始,仅遍历传出:RELTYPE 关系,并在到达 a:foo 标记节点时终止扩展(label 过滤器中的 'foo' 之前的/表示这是标签上的终止过滤器)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM