How to write a PGQL query that matches to vertices with an unknown number of hops between them?

73 Views Asked by At

I have a relation database schema like:

ERD

DDL

CREATE TABLE Persons
(
 Name VARCHAR2(100) NOT NULL,
 CONSTRAINT Persons_PK PRIMARY KEY (Name)
);
 
CREATE TABLE Groups
(
 Name VARCHAR2(100),
 CONSTRAINT Groups_PK PRIMARY KEY (Name)
);
 
CREATE TABLE Person_Group_Connections
(
 Person_Name VARCHAR2(100),
 Group_Name VARCHAR2(100),
 CONSTRAINT PG_Connection_PK PRIMARY KEY (Person_Name, Group_Name),
 CONSTRAINT PG_Connection_Persons_FK FOREIGN KEY (Person_Name) REFERENCES Persons (Name),
 CONSTRAINT PG_Connection_Groups_FK FOREIGN KEY (Group_Name) REFERENCES Groups (Name)
);

insert into Persons (name) values ('Person A');
insert into Persons (name) values ('Person B');
insert into Persons (name) values ('Person C');
insert into Persons (name) values ('Person D');
insert into Persons (name) values ('Person E');
insert into Persons (name) values ('Person F');

insert into Groups (name) values ('Group 1');
insert into Groups (name) values ('Group 2');
insert into Groups (name) values ('Group 3');
insert into Groups (name) values ('Group 4');

insert into Person_Group_Connections (Person_Name, Group_Name) values ('Person A', 'Group 1');
insert into Person_Group_Connections (Person_Name, Group_Name) values ('Person B', 'Group 1');
insert into Person_Group_Connections (Person_Name, Group_Name) values ('Person B', 'Group 2');
insert into Person_Group_Connections (Person_Name, Group_Name) values ('Person C', 'Group 2');
insert into Person_Group_Connections (Person_Name, Group_Name) values ('Person D', 'Group 2');
insert into Person_Group_Connections (Person_Name, Group_Name) values ('Person D', 'Group 3');
insert into Person_Group_Connections (Person_Name, Group_Name) values ('Person E', 'Group 3');
insert into Person_Group_Connections (Person_Name, Group_Name) values ('Person F', 'Group 3');

Then I define a Proerty Graph with Vertices and Edges:

CREATE PROPERTY GRAPH my_graph
  VERTEX TABLES (
    Persons LABEL Person PROPERTIES ( name ),
    Groups LABEL Group PROPERTIES ( name )
  )
  EDGE TABLES (
    Person_Group_Connections as PG_Connection
    SOURCE KEY ( person_name ) REFERENCES Persons ( name )
    DESTINATION KEY (group_name) REFERENCES Groups ( name )
    LABEL person_connected_to_group
  ) OPTIONS (PG_VIEW);

Graph

How would you write a query that links two "Person" vertices together without know the number of hops?

Eg: How is "Person A" connected to "Person F" I'd expect the query to return: "Person A" "Person B" "Person D" "Person F" Or "Person A" → "Group 1" → "Person B" → "Group 2" → "Person D" → "Group 3" → "Person F"

Or would there be a better way to define the Property Graph?

SELECT *
FROM MATCH (P1:Person)-/:person_connected_to_group*/->(g:Group)<-/:person_connected_to_group*/-(P2:Person) on my_graph
WHERE P1.name = 'Person 1' and P2.name = 'Person 2'
1

There are 1 best solutions below

0
Ryota Yamanaka On

Could you check if the queries below meet your requirements?

Using PG View:

SELECT COUNT(e) AS distance
FROM MATCH ANY (p1:Person)-[e]-+(p2:Person) ON my_graph
WHERE p1.name = 'Person A' AND p2.name = 'Person F'
+----------+
| DISTANCE |
+----------+
| 6        |
+----------+

Graph Server (PGX) also supports the query below:

SELECT ELEMENT_NUMBER(v1) AS num, v1.name
FROM MATCH ANY (p1:Person)-[g]-+(p2:Person) ON my_graph
     ONE ROW PER STEP (v1, e, v2)
WHERE p1.name = 'Person A' AND p2.name = 'Person F'
ORDER BY num
+----------------+
| num | name     |
+----------------+
| 1   | Person A |
| 3   | Group 1  |
| 5   | Person B |
| 7   | Group 2  |
| 9   | Person D |
| 11  | Group 3  |
+----------------+