Reputation: 3189
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!
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
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
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