cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Repeating matches

oaklodge
Node Link

I want to model a system as a graph. I'm starting small; I just want to model the power flow. So I created this graph:

CREATE (n:World  {name:"Power", provides:"power"});
CREATE (n:System {name:"Connector", carries:"power"});
CREATE (n:System {name:"Power Supply", consumes:"power"});
MATCH  (x:World  {name:"Power"}), (y:System {name:"Connector"}) MERGE (x)-[:power {carries:"power"}]->(y);
MATCH  (x:System {name:"Connector"}), (y:System {name:"Power Supply"}) MERGE (x)-[:power {carries:"power"}]->(y);

Now I want to know if the "Power Supply" (which consumes power), is actually connected via edges (which must carry power) and nodes (which also must carry power) to a node that provides power.

My first try went something like this:

MATCH (x {provides:'power'})-[{carries:"power"}]->(y {carries:"power"})-[{carries:"power"}]->(z {consumes:"power"}) RETURN x,y,z

But that only works because there are 3 nodes. If there were 4 it would not work. Example:

CREATE (n:World  {name:"Power", provides:"power"});
CREATE (n:World  {name:"Cable", carries:"power"});
CREATE (n:System {name:"Connector", carries:"power"});
CREATE (n:System {name:"Power Supply", consumes:"power"});
MATCH  (x:World  {name:"Power"}), (y:World {name:"Cable"}) MERGE (x)-[:power {carries:"power"}]->(y);
MATCH  (x:World  {name:"Cable"}), (y:System {name:"Connector"}) MERGE (x)-[:power {carries:"power"}]->(y);
MATCH  (x:System {name:"Connector"}), (y:System {name:"Power Supply"}) MERGE (x)-[:power {carries:"power"}]->(y);

So my question is: How do I get the "(y {carries:"power"})-[{carries:"power"}]->" part to repeat until it finds a consumes power node?

1 ACCEPTED SOLUTION

Hi oaklodge,

welcome to the Neo4j community!

Concerning your question, this probably goes into the direction of what you want:

MATCH (x {provides:'power'})-[*0..3{carries:"power"}]->(y {carries:"power"})-[*0..3{carries:"power"}]->(z {consumes:"power"}) RETURN x,y,z

By writing "*0..3" you state how many edges you want in between. In this case I put down 0 to 3 edges. You can adapt that accordingly.

Regards,
Elena

View solution in original post

4 REPLIES 4

Hi oaklodge,

welcome to the Neo4j community!

Concerning your question, this probably goes into the direction of what you want:

MATCH (x {provides:'power'})-[*0..3{carries:"power"}]->(y {carries:"power"})-[*0..3{carries:"power"}]->(z {consumes:"power"}) RETURN x,y,z

By writing "*0..3" you state how many edges you want in between. In this case I put down 0 to 3 edges. You can adapt that accordingly.

Regards,
Elena

oaklodge
Node Link

Sorry for the delayed response. I posted this question and then went on vacation... 😉

Thanks for the answer. That works, but what if I don't know how many edges there might be, i.e. is there something like "*0..n"?

Hello @oaklodge

You have a list here of all possibilities. You can use * if you don't want to specify a limit.

Regards,
Cobra

oaklodge
Node Link

Thank you @elena.kohlwey and @Cobra for your help! This is what I settled on:

MATCH (x {provides:'power'})-[*{carries:"power"}]->(y {carries:"power"})-[*{carries:"power"}]->(z {consumes:"power"}) RETURN x,y,z