プログラミング
DuckPGQ – グラフワークロードのためのDuckDBコミュニティ拡張機能
DuckPGQ – A DuckDB community extension for graph workloads (duckpgq.org)
要約
DuckPGQは、SQL/PGQ標準をサポートするグラフワークロード向けのDuckDBコミュニティ拡張機能です。DuckDBのパワーを活用し、分析ワークフローに直接、高性能なSQLベースのグラフクエリ機能をもたらします。この拡張機能は、SQL/PGQ標準に準拠したグラフパターンマッチング、DuckDBによる効率的なインプロセスグラフ分析、簡単なインストール、そしてオープンソースであることを特徴としています。
全文翻訳
DuckPGQ
DuckPGQは、SQL/PGQ標準をサポートするグラフワークロードのためのDuckDBコミュニティ拡張機能です。DuckDBのパワーを活用し、高パフォーマンスなSQLベースのグラフクエリ機能を分析ワークフローに直接もたらします。
インストールとロード
CLIPythonNodeJSRJava
INSTALL duckpgq FROM community;
LOAD duckpgq;
import duckdb
conn = duckdb.connect()
conn.install_extension("duckpgq", repository="community")
conn.load_extension("duckpgq")
import {
DuckDBInstance
} from '@duckdb/node-api';
const instance = await DuckDBInstance.create();
const connection = await instance.connect();
await connection.run("INSTALL duckpgq FROM community");
await connection.run("LOAD duckpgq");
library(duckdb)
con <- dbConnect(duckdb())
dbExecute(con, "INSTALL duckpgq FROM community")
dbExecute(con, "LOAD duckpgq")
Connection conn = DriverManager.getConnection("jdbc:duckdb:");
Statement st = conn.createStatement();
st.execute("INSTALL duckpgq FROM community");
st.execute("LOAD duckpgq");
主な機能
* SQL/PGQ標準
SQL:2023標準に準拠したグラフパターンマッチングをサポートします。
* 高パフォーマンス
DuckDBを活用し、効率的なインプロセスグラフ分析を実現します。
* 簡単なインストール
依存関係なしで、簡単なセットアッププロセスを通じてDuckDBとシームレスに統合できます。
* オープンソース
コミュニティ主導で拡張可能、かつ無料で利用できます。
ドメインを横断したDuckPGQの探索
ソーシャルネットワーク
航空データ
金融データ
セットアップ
ATTACH 'https://github.com/Dtenwolde/duckpgq-docs/raw/refs/heads/main/datasets/snb.duckdb';
use snb;
install duckpgq from community;
load duckpgq;
CREATE or replace PROPERTY GRAPH snb
VERTEX TABLES (
Person,
Forum
)
EDGE TABLES (
Person_knows_person
SOURCE KEY (Person1Id) REFERENCES Person (id)
DESTINATION KEY (Person2Id) REFERENCES Person (id)
LABEL knows,
Forum_hasMember_Person
SOURCE KEY (ForumId) REFERENCES Forum (id)
DESTINATION KEY (PersonId) REFERENCES Person (id)
LABEL hasMember
);
最短経路クエリ
相互友達の検索
最も人気のある人々
最もフォローされている人物のフォーラムカウント
-- 1人の人物から他のすべての人物への最短経路を見つける
FROM GRAPH_TABLE (
snb
MATCH p = ANY SHORTEST (p1:person WHERE p1.id = 14)-[k:knows]->*(p2:person)
COLUMNS (
p1.id,
p2.id as other_person_id,
element_id(p),
path_length(p)
)
);
-- 2人のユーザー間の相互友達を見つける
FROM GRAPH_TABLE (
snb
MATCH (p1:Person WHERE p1.id = 16)-[k:knows]->(p2:Person)<-[k2:knows]-(p3:Person WHERE p3.id = 32)
COLUMNS (
p2.firstName
)
);
-- 最も人気のある3人を検索する
FROM GRAPH_TABLE (
snb
MATCH (follower:Person)-[follows:knows]->(person:Person)
COLUMNS (
person.id AS personID,
person.firstname,
person.lastname,
follower.id AS followerID
)
)
SELECT
personID,
firstname,
lastname,
COUNT(followerID) AS numFollowers
GROUP BY ALL
ORDER BY numFollowers DESC
LIMIT 3;
-- 最もフォローされている人物が投稿したフォーラムの数
WITH mfp AS (
FROM GRAPH_TABLE (
snb
MATCH (follower:Person)-[follows:knows]->(person:Person)
COLUMNS (
person.id AS personID,
person.firstname,
follower.id AS followerID
)
)
SELECT
personID,
firstname,
COUNT(followerID) AS numFollowers
GROUP BY ALL
ORDER BY numFollowers DESC
LIMIT 1
)
SELECT
mfp.personID,
mfp.firstname,
mfp.numFollowers,
count(mem.forumId) forumCount
FROM mfp,
GRAPH_TABLE (
snb
MATCH (person:Person)<-[fhm:hasMember]-(f:Forum)
COLUMNS (
person.id AS personID,
f.id as forumId
)
) mem
WHERE
mfp.personID = mem.personID
GROUP BY ALL;
セットアップ
ATTACH 'https://github.com/Dtenwolde/duckpgq-docs/raw/refs/heads/airline-data/datasets/airline-data-small.duckdb' as airline;
use airline;
install duckpgq from community;
load duckpgq;
CREATE PROPERTY GRAPH flight_graph
VERTEX TABLES (
aircrafts_data,
airports_data,
bookings,
flights,
tickets,
seats
)
EDGE TABLES (
route
SOURCE KEY (departure_airport) REFERENCES airports_data(airport_code)
DESTINATION KEY (arrival_airport) REFERENCES airports_data(airport_code),
ticket_flights
SOURCE KEY (ticket_no) REFERENCES tickets(ticket_no)
DESTINATION KEY (flight_id) REFERENCES flights(flight_id),
bookings_tickets
SOURCE KEY (book_ref) REFERENCES bookings(book_ref)
DESTINATION KEY (ticket_no) REFERENCES tickets(ticket_no),
boarding_passes
SOURCE KEY (ticket_no) REFERENCES tickets(ticket_no)
DESTINATION KEY (seat_no) REFERENCES seats(seat_no)
);
空港間の最短ルート
平均して最も高価な座席
FROM (
SELECT unnest(flights) AS flights
FROM GRAPH_TABLE (
flight_graph
MATCH o = ANY SHORTEST (a:airports_data WHERE a.airport_code = 'UKX') -[fr:route]->* (a2:airports_data WHERE a2.airport_code = 'CNN')
COLUMNS (
edges(o) AS flights
)
)
)
JOIN route f ON f.rowid = flights;
FROM GRAPH_TABLE (
flight_graph
MATCH (b:bookings)-[bt:bookings_tickets]->(t:tickets)-[bp:boarding_passes]->(s:seats)
)
SELECT
round(avg(total_amount), 2) avg_amount,
seat_no
GROUP BY seat_no
ORDER BY avg_amount DESC;
セットアップ
ATTACH 'https://github.com/Dtenwolde/duckpgq-docs/raw/refs/heads/main/datasets/finbench.duckdb' AS finbench;
use finbench;
INSTALL duckpgq FROM community;
LOAD duckpgq;
CREATE OR REPLACE PROPERTY GRAPH finbench
VERTEX TABLES (
Account,
Company,
Loan,
Medium,
Person
)
EDGE TABLES (
AccountRepayLoan
SOURCE KEY (accountId) REFERENCES Account (accountId)
DESTINATION KEY (loanId) REFERENCES Loan (loanId)
LABEL repay,
AccountTransferAccount
SOURCE KEY (fromId) REFERENCES Account (accountId)
DESTINATION KEY (toId) REFERENCES Account (AccountId)
LABEL transfer,
AccountWithdrawAccount
SOURCE KEY (fromId) REFERENCES Account (accountId)
DESTINATION KEY (toId) REFERENCES Account (AccountId)
LABEL withdraw,
CompanyApplyLoan
SOURCE KEY (companyId) REFERENCES Company (companyId)
DESTINATION KEY (loanId) REFERENCES Loan (loanId)
LABEL companyApply,
CompanyGuaranteeCompany
SOURCE KEY (fromId) REFERENCES Company (companyId)
DESTINATION KEY (toId) REFERENCES Company (companyId)
LABEL companyGuarantee,
CompanyInvestCompany
SOURCE KEY (investorId) REFERENCES Company (companyId)
DESTINATION KEY (companyId) REFERENCES Company (companyId)
LABEL companyInvest,
CompanyOwnAccount
SOURCE KEY (companyId) REFERENCES Company (companyId)
DESTINATION KEY (accountId) REFERENCES Account (accountId)
LABEL companyOwn,
LoanDepositAccount
SOURCE KEY (loanId) REFERENCES Loan (loanId)
DESTINATION KEY (accountId) REFERENCES Account (accountId)
LABEL deposit,
MediumSignInAccount
SOURCE KEY (mediumId) REFERENCES Medium (mediumId)
DESTINATION KEY (accountId) REFERENCES Account (accountId)
LABEL signIn,
PersonApplyLoan
SOURCE KEY (personId) REFERENCES Person (personId)
DESTINATION KEY (loanId) REFERENCES Loan (loanId)
LABEL personApply,
PersonGuaranteePerson
SOURCE KEY (fromId) REFERENCES Person (personId)
DESTINATION KEY (toId) REFERENCES Person (personId)
LABEL personGuarantee,
PersonInvestCompany
SOURCE KEY (investorId) REFERENCES Person (personId)
DESTINATION KEY (companyId) REFERENCES Company (companyId)
LABEL personInvest,
PersonOwnAccount
SOURCE KEY (personId) REFERENCES Person (personId)
DESTINATION KEY (accountId) REFERENCES Account (accountId)
LABEL personOwn
);
転送によるブロックされたアカウントの検索
高額転送を時間でフィルタリングする
FROM GRAPH_TABLE (
finbench
MATCH (src:Account where src.accountId = 16607023625929101) <-[e1:transfer]-(mid:Account) -[e2:transfer]->(dst:Account where dst.isBlocked = true)
COLUMNS (
src.accountId as src_id,
dst.accountId as dst_id
)
)
SELECT src_id, dst_id WHERE src_Id <> dst_id;
FROM GRAPH_TABLE (
finbench
MATCH (src:Account)-[e:Transfer]->(dst:Account)
WHERE '2022-07-13 09:18:33.137' < e.createtime AND e.createtime < '2022-09-03 02:31:47.812' AND e.amount > 4829783
);
DuckPGQの背後にあるもの
Daniël ten Wolde
DuckPGQのリード開発者であり、CWIの博士課程学生で、グラフ分析とデータベースシステムを専門としています。
GitHub
Bluesky
LinkedIn
WIP
免責事項
DuckPGQは現在、研究プロジェクトであり、まだ開発途上です。探索や実験を奨励しますが、バグ、不完全な機能、または予期しない動作が存在する可能性があることに注意してください。拡張機能を改善および進化させるのに役立つフィードバックやバグレポートを高く評価します。お気軽にご連絡ください。