starting with memgraph so it might be obvious, but struggling to find the right query to find nodes with a number of parallel connections to another.
For my use case I'm representing network devices which each of them have one or more interfaces. There are connections from interface to interface. For example:
(Device1) - (interface1) ----- Connection ---- (interface 3) - (Device 2)
- (interface2) ----- Connection ---- (interface 4) -
There are devices with 0 to 100s of interfaces, and there might be parallel links between two given devices.
I'm creating the data as follows:
CREATE (d1:Device {name: 'd1', id:1})
CREATE (if1:Interface {name:'g0', id:2})
CREATE (if1)-[:IS_IN]->(d1)
return d1, if1;
CREATE (d1:Device {name: 'd2', id:3})
CREATE (if1:Interface {name:'g0', id:4})
CREATE (if1)-[:IS_IN]->(d1)
return d1, if1;
MATCH (if1:Interface {id:3})
MATCH (if2:Interface {id:4})
CREATE (if1)-[:CONNECTED]->(if2)
return if1,if2;
The query I'm trying to create now is: "Find me which devices have 2 (or any other number) of parallel connections between them.
The obvious query forgetting about parallel links is
MATCH (d1)-[i1:IS_IN]-(if1:Interface)-[c:CONNECTED]-(if2:Interface)-[i2:IS_IN]-(d2)
return if1,if2,d1,d2;
Which for example returns
+-----------------------------------+-----------------------------------+-----------------------------------+-----------------------------------+
| if1 | if2 | d1 | d2 |
+-----------------------------------+-----------------------------------+-----------------------------------+-----------------------------------+
| (:Interface {id: 6, name: "g0"}) | (:Interface {id: 2, name: "g0"}) | (:Device {id: 5, name: "d2"}) | (:Device {id: 1, name: "d1"}) |
| (:Interface {id: 8, name: "g1"}) | (:Interface {id: 4, name: "g1"}) | (:Device {id: 7, name: "d2"}) | (:Device {id: 3, name: "d1"}) |
| (:Interface {id: 2, name: "g0"}) | (:Interface {id: 6, name: "g0"}) | (:Device {id: 1, name: "d1"}) | (:Device {id: 5, name: "d2"}) |
| (:Interface {id: 4, name: "g1"}) | (:Interface {id: 8, name: "g1"}) | (:Device {id: 3, name: "d1"}) | (:Device {id: 7, name: "d2"}) |
| (:Interface {id: 16, name: "g0"}) | (:Interface {id: 14, name: "g0"}) | (:Device {id: 15, name: "d4"}) | (:Device {id: 13, name: "d3"}) |
| (:Interface {id: 14, name: "g0"}) | (:Interface {id: 16, name: "g0"}) | (:Device {id: 13, name: "d3"}) | (:Device {id: 15, name: "d4"}) |
+-----------------------------------+-----------------------------------+-----------------------------------+-----------------------------------
The clause I'm looking is to have the same device 'name'. So for this query the result should be device d1 and d2, but not d3 or d4
There are different ways to approach this, but maybe node.degree_in() procedure from the MAGE library will be useful here. Does query:
help in your case?
Besides that, I would recommend using the correct relationship direction when querying. The count() function and RETURN DISTINCT might also help.
For quicker communication and help, feel free to join our Discord server.