简体   繁体   中英

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

Suppose my graph database has a 'flow' of foo nodes. in between each foo nodes might be any number of bar , bar1 , bar2 , ... barN nodes which ultimately connect to the next foo node.

So, all of these are possible

  • (a:foo)-->(:bar)-->(b:foo)
  • (b:foo)-->(:bar)-->(c:foo)-->(:bar1)-->(d: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

For the above examples, the solution should return:

  • a, b
  • b, c
  • c, d
  • a, c

Solution should NOT include the following, which have foo nodes between them:

  • b, d
  • a, d

What I've tried. this returns all foo pairs that connect, regardless of what's in between.

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.

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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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