You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently we only support ANY SHORTEST with the *. However, we also need to add support for ALL SHORTEST, which would return all the paths between A and B with the same shortest path length. Because this is ALL paths, it cannot work together with *, since that could lead to infinite results. Therefore, we will enforce this to only work on quantified path patterns. For instance, p = ALL SHORTEST MATCH (a:Person)-[k:Knows]->{1,3}(b:Person) or even just ALL SHORTEST MATCH (a:Person)-[k:Knows]->{1,3}(b:Person)
The current approach is to use WITH RECURSIVE internally, with this moved to a separate CTE. The RECURSIVE statement consists of two parts: 1. Non-recursive step, executed once as the first step. 2. Recursive step, executed until the resulting step is empty.
An advantage that DuckDB provides us is the fact that the result does not need to be monotonically increasing, i.e. we can filter out tuples that will not become the shortest path already during the recursive steps.
The current query that I am considering is:
CREATETABLEperson_knows_person (
Person1Id BIGINT,
Person2Id BIGINT,
creationDate TIMESTAMP
);
INSERT INTO person_knows_person (Person1Id, Person2Id, creationDate) VALUES
(1, 2, '2024-01-01 10:00:00'),
(2, 3, '2024-01-01 11:00:00'),
(1, 4, '2024-01-01 10:30:00'),
(4, 3, '2024-01-01 11:30:00');
WITH RECURSIVE AllShortestPaths AS (
-- Non-recursive step: Start from the given Person1IdSELECT
Person1Id,
Person2Id,
1AS depth, -- Start with depth 1
ARRAY[Person1Id, Person2Id] ASpath-- Store the path as an arrayFROM Person_knows_person
WHERE Person1Id =1-- Starting Person1IdUNION ALL-- Recursive step: Expand paths and group by Person2Id to retain shortest pathsSELECTr.Person1Id,
rt.Person2Id,
MIN(r.depth+1) AS depth, -- Keep the minimum depth for each Person2Id
list_append(r.path, rt.Person2Id) ASpath-- Extend the pathFROM AllShortestPaths r
JOIN Person_knows_person rt
ONr.Person2Id=rt.Person1IdWHEREr.depth<3-- Limit depth to 3GROUP BYr.Person1Id, rt.Person2Id, r.path-- Group by relevant columns
)
-- Final selection: Return all paths with detailsSELECT DISTINCTpath,
depth
FROM AllShortestPaths
ORDER BY depth, path;
In this case, the starting point is node 1, but it could be that there are multiple nodes from which we wish to explore. In that case we use WHERE Person1Id IN (1,4) -- Starting Person1Id instead.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Currently we only support
ANY SHORTEST
with the*
. However, we also need to add support forALL SHORTEST
, which would return all the paths betweenA
andB
with the same shortest path length. Because this isALL
paths, it cannot work together with*
, since that could lead to infinite results. Therefore, we will enforce this to only work on quantified path patterns. For instance,p = ALL SHORTEST MATCH (a:Person)-[k:Knows]->{1,3}(b:Person)
or even justALL SHORTEST MATCH (a:Person)-[k:Knows]->{1,3}(b:Person)
The current approach is to use
WITH RECURSIVE
internally, with this moved to a separate CTE. TheRECURSIVE
statement consists of two parts: 1. Non-recursive step, executed once as the first step. 2. Recursive step, executed until the resulting step is empty.An advantage that DuckDB provides us is the fact that the result does not need to be monotonically increasing, i.e. we can filter out tuples that will not become the shortest path already during the recursive steps.
The current query that I am considering is:
In this case, the starting point is node 1, but it could be that there are multiple nodes from which we wish to explore. In that case we use
WHERE Person1Id IN (1,4) -- Starting Person1Id
instead.Beta Was this translation helpful? Give feedback.
All reactions