philippe
philippe

Reputation: 3189

neo4j: does not follow relationships until end

I am trying to represent a network configuration with neo4j. Here is the Cyper script I have been using so far :

 CREATE (router1:Router {name:'router1', defaultgw:'192.168.123.1'})
 CREATE (router2:Router {name:'router2', defaultgw:'172.31.39.1'})
 CREATE (gateway1:Gateway {name:'gateway1', ip:'192.168.123.1' })
 CREATE (network1:Network {name:'network1', cidr:'192.168.123.0/24'})
 CREATE (network2:Network {name:'network2', cidr:'10.23.47.0/24'})
 CREATE (network3:Network {name:'network3', cidr:'172.31.39.0/24'})
 CREATE (server10:Server {hostname:'server10', ip:'172.31.39.10'})
 CREATE (server1:Server {hostname:'server1', ip:'192.168.123.7'})
 CREATE (server2:Server {hostname:'server2', ip:'192.168.123.9'})
 CREATE (server3:Server {hostname:'server3', ip:'192.168.123.10', ip:'10.23.47.7'})
 CREATE (server4:Server {hostname:'server4', ip:'192.168.123.13'})
 CREATE (server5:Server {hostname:'server5', ip:'192.168.123.23'})
 CREATE (server6:Server {hostname:'server6', ip:'192.168.123.15', ip:'10.23.47.17'})
 CREATE
   (gateway1)-[:CONNECTED_TO {}]->(router1),
   (router2)-[:CONNECTED_TO {}]->(network3),
   (router1)-[:CONNECTED_TO {}]->(network1),
   (router1)-[:CONNECTED_TO {}]->(network2),
   (router1)-[:CONNECTED_TO {}]->(router2),
   (network1)-[:CONNECTED_TO {}]->(server1),
   (network1)-[:CONNECTED_TO {}]->(server2),
   (network1)-[:CONNECTED_TO {}]->(server3),
   (network2)-[:CONNECTED_TO {}]->(server3),
   (network1)-[:CONNECTED_TO {}]->(server4),
   (network1)-[:CONNECTED_TO {}]->(server5),
   (network1)-[:CONNECTED_TO {}]->(server6),
   (network2)-[:CONNECTED_TO {}]->(server6),
   (network3)-[:CONNECTED_TO {}]->(server10)
 WITH gateway1 AS g
   MATCH (g)-[:CONNECTED_TO]->(r)-[:CONNECTED_TO]->(n)-[:CONNECTED_TO]->(s) RETURN g,r,n,s
 ;

However, the MATCH case does not let the rendering flow until the servers for the third network!

Servers related to network3 are not getting represented

What is wrong with my request and how can it be improved ? Is there an other way to make this request, i.e. to represent every nodes having relationships or not with another instead of only those related to a single (here, gateway1) origin ?

Many thanks!

Upvotes: 1

Views: 114

Answers (2)

cybersam
cybersam

Reputation: 67019

If you are asking for a query to get all the nodes in the subtree rooted at gateway1, then your MATCH does not work because it only matches paths with exactly 3 CONNECTED_TO relationships. The path to server10 requires 4 hops.

To return full paths with 1 or more CONNECTED_TO relationships rooted at gateway1, this should work (the WHERE clause filters out paths where x is a non-leaf node):

...
WITH gateway1 AS g
MATCH p=(g)-[:CONNECTED_TO*]->(x)
WHERE NOT (x)-[:CONNECTED_TO]->()
RETURN p;

And, if you also want to be able to return just the root gateway node when it has no other nodes in its subgraph, you can change * to *0..:

...
WITH gateway1 AS g
MATCH p=(g)-[:CONNECTED_TO*0..]->(x)
WHERE NOT (x)-[:CONNECTED_TO]->()
RETURN p;

Upvotes: 4

Dave Bennett
Dave Bennett

Reputation: 11216

As @cybersam says the servers in network 3 are four hops away because they need to traverse to routers.

An alternative to his solution if you know you are looking for :Server nodes 3 to 4 hops out you could use a query like the following.

...
WITH gateway1 AS g
MATCH p=(g)-[:CONNECTED_TO*3..4]->(:Server)
RETURN p

Upvotes: 1

Related Questions