DuckPGQ – A DuckDB community extension for graph workloads

rzk1 pts0 comments

DuckPGQ

Skip to content

Join us on Discord!

Initializing search

DuckPGQ

WIP Disclaimer

Documentation

Resources

WIP Disclaimer

DuckPGQ

DuckPGQ is a DuckDB community extension for graph workloads that supports the SQL/PGQ standard.

Leveraging the power of DuckDB to bring high-performance, SQL-based graph query capabilities directly to your analytical workflows.

Install and Load DuckPGQ

CLIPythonNodeJSRJava

INSTALL duckpgq FROM community;<br>LOAD duckpgq;

import duckdb<br>conn = duckdb.connect()<br>conn.install_extension("duckpgq", repository="community")<br>conn.load_extension("duckpgq")

import { DuckDBInstance } from '@duckdb/node-api';<br>const instance = await DuckDBInstance.create();<br>const connection = await instance.connect();<br>await connection.run("INSTALL duckpgq FROM community");<br>await connection.run("LOAD duckpgq");

library(duckdb)<br>con dbConnect(duckdb())<br>dbExecute(con, "INSTALL duckpgq FROM community")<br>dbExecute(con, "LOAD duckpgq")

Connection conn = DriverManager.getConnection("jdbc:duckdb:");<br>Statement st = conn.createStatement();<br>st.execute("INSTALL duckpgq FROM community");<br>st.execute("LOAD duckpgq");

Key Features

SQL/PGQ Standard

Supports graph pattern matching with SQL/PGQ, following the SQL:2023 standard.

High Performance

Leverages DuckDB for efficient, in-process graph analytics.

Easy To Install

Seamlessly integrate with DuckDB through a simple setup process, requiring no dependencies.

Open Source

Community-driven, extensible, and free to use.

Explore DuckPGQ Across Domains

Social NetworksAirline DataFinancial Data

Setup<br>ATTACH 'https://github.com/Dtenwolde/duckpgq-docs/raw/refs/heads/main/datasets/snb.duckdb';

use snb;<br>install duckpgq from community;<br>load duckpgq;

CREATE or replace PROPERTY GRAPH snb<br>VERTEX TABLES (<br>Person, Forum<br>EDGE TABLES (<br>Person_knows_person SOURCE KEY (Person1Id) REFERENCES Person (id)<br>DESTINATION KEY (Person2Id) REFERENCES Person (id)<br>LABEL knows,<br>Forum_hasMember_Person SOURCE KEY (ForumId) REFERENCES Forum (id)<br>DESTINATION KEY (PersonId) REFERENCES Person (id)<br>LABEL hasMember<br>);

Shortest Path QueryFind Mutual FriendsMost Popular PeopleForum count of the most-followed person

-- find the shortest path from one person to all other persons<br>FROM GRAPH_TABLE (snb<br>MATCH p = ANY SHORTEST (p1:person WHERE p1.id = 14)-[k:knows]->*(p2:person)<br>COLUMNS (p1.id, p2.id as other_person_id, element_id(p), path_length(p))<br>);

-- Find mutual friends between two users<br>FROM GRAPH_TABLE (snb<br>MATCH (p1:Person WHERE p1.id = 16)-[k:knows]->(p2:Person)[k2:knows]-(p3:Person WHERE p3.id = 32)<br>COLUMNS (p2.firstName)<br>);

-- Find the 3 most popular people<br>FROM GRAPH_TABLE (snb<br>MATCH (follower:Person)-[follows:knows]->(person:Person)<br>COLUMNS (person.id AS personID, person.firstname, person.lastname, follower.id AS followerID)<br>SELECT personID, firstname, lastname, COUNT(followerID) AS numFollowers<br>GROUP BY ALL<br>ORDER BY numFollowers DESC<br>LIMIT 3;

-- Number of forums posted on by the most followed person<br>WITH<br>mfp AS (<br>FROM GRAPH_TABLE (snb<br>MATCH (follower:Person)-[follows:knows]->(person:Person)<br>COLUMNS (person.id AS personID, person.firstname, follower.id AS followerID)<br>SELECT personID, firstname, COUNT(followerID) AS numFollowers<br>GROUP BY ALL ORDER BY numFollowers DESC LIMIT 1<br>FROM<br>mfp,<br>GRAPH_TABLE (snb<br>MATCH (person:Person)[fhm:hasMember]-(f:Forum)<br>COLUMNS (person.id AS personID, f.id as forumId)<br>) mem<br>SELECT mfp.personID, mfp.firstname, mfp.numFollowers, count(mem.forumId) forumCount<br>WHERE mfp.personID = mem.personID<br>GROUP BY ALL;

Setup<br>ATTACH 'https://github.com/Dtenwolde/duckpgq-docs/raw/refs/heads/airline-data/datasets/airline-data-small.duckdb' as airline;

use airline;<br>install duckpgq from community;<br>load duckpgq;

CREATE PROPERTY GRAPH flight_graph<br>VERTEX TABLES (<br>aircrafts_data, airports_data,<br>bookings, flights,<br>tickets, seats<br>EDGE TABLES (<br>route<br>SOURCE KEY (departure_airport) REFERENCES airports_data(airport_code)<br>DESTINATION KEY (arrival_airport) REFERENCES airports_data(airport_code),<br>ticket_flights<br>SOURCE KEY (ticket_no) REFERENCES tickets(ticket_no)<br>DESTINATION KEY (flight_id) REFERENCES flights(flight_id),<br>bookings_tickets<br>SOURCE KEY (book_ref) REFERENCES bookings(book_ref)<br>DESTINATION KEY (ticket_no) REFERENCES tickets(ticket_no),<br>boarding_passes<br>SOURCE KEY (ticket_no) REFERENCES tickets(ticket_no)<br>DESTINATION KEY (seat_no) REFERENCES seats(seat_no)<br>);

Shortest Route Between AirportsMost Expensive Seats on Average

FROM (<br>SELECT unnest(flights) AS flights<br>FROM GRAPH_TABLE (<br>flight_graph<br>MATCH o = ANY SHORTEST (a:airports_data WHERE a.airport_code = 'UKX')<br>-[fr:route]->*<br>(a2:airports_data WHERE a2.airport_code = 'CNN')<br>COLUMNS (edges(o) AS flights)<br>JOIN route f<br>ON f.rowid = flights;

FROM GRAPH_TABLE (<br>flight_graph<br>MATCH (b:bookings)-[bt:bookings_tickets]->(t:tickets)-[bp:boarding_passes]->(s:seats)<br>SELECT round(avg(total_amount), 2) avg_amount, seat_no<br>GROUP BY seat_no<br>ORDER BY avg_amount DESC;

Setup<br>ATTACH...

person duckpgq from duckdb references community

Related Articles