Pernah mikir gak sih: "kenapa nyari shortest path antara dua akun, atau deteksi chain transfer yang mencurigakan, kok harus setup database graph khusus dulu?" Selama ini, graph analytics identik sama solusi berat kayak Neo4j atau TigerGraph — powerful, tapi bawa overhead operasional gede: server sendiri, sizing memory, belajar bahasa query baru, ngurus backup. Padahal banyak use case graph di dunia nyata itu sifatnya analitis dan batch, bukan transaksional real-time.
Nah, di situ DuckPGQ masuk. Ini extension resmi komunitas untuk DuckDB yang nambahin kemampuan property graph queries langsung di atas data yang ada — pakai SQL/PGQ standar ISO ataupun syntax ala Cypher — tanpa nambah satu pun komponen database baru. Di artikel ini bakal dibahas apa aja yang bisa dilakukan, contoh query nyatanya, sampai kapan sebaiknya gak dipake. Santai, langsung gas.
Kenapa Butuh Graph Analytics Tanpa Database Baru
Coba perhatiin workload data modern. Banyak banget yang polanya relational + analytical: data ngumpul di Postgres, diproses batch ke warehouse, dianalisis pake SQL. Masalahnya, begitu ada kebutuhan graph — misalnya "temen dari temen siapa aja" atau "ada gak sih chain 3-hop antara dua rekening?" — langsung kepaksa ngomong sama tim ops soal provisioning database graph.
Padahal gak semua kasus butuh itu. Kalau query graph jalan sebagai batch job atau bagian dari pipeline ETL (bukan traversal real-time dengan latency milidetik), nambahin satu database khusus itu cuma nambahin permukaan operasional: satu service lagi buat di-monitor, satu storage lagi buat di-backup, satu skill lagi buat dikuasai tim. DuckPGQ ngilangin masalah itu — graph query jadi citizen kelas satu di database yang udah dipake.
DuckPGQ Itu Apa Sih?
DuckPGQ (diucapin "duck-p-g-q") adalah community extension untuk DuckDB yang dikembangin oleh tim riset CWI (Centrum Wiskunde & Informatica) — institusi yang sama yang melahirkan MonetDB. Extension ini ngimplementasiin standar SQL/PGQ (Property Graph Queries) dari SQL:2023, plus subset dari syntax Cypher yang familiar buat pengguna Neo4j.
Yang bikin beda dari solusi lain: DuckPGQ gak nyimpen data secara terpisah. Tabel DuckDB biasa dideklarasiin sebagai vertex dan edge dari sebuah property graph, terus query-nya jalan zero-copy di atas data yang udah ada. Artinya:
- Gak ada ETL ke database lain — data tetap di tempatnya, graph cuma lapisan pandangan (view) di atasnya
- SQL/PGQ standar ISO — syntax pattern matching yang tetap kerasa kayak SQL biasa
- Subset Cypher — buat yang udah terbiasa arrow syntax ala Neo4j, langsung nyambung
- Interop Python — hasil query bisa langsung balik jadi DataFrame Pandas/Polars
Buat yang lagi bangun pipeline data analytics, konsep "data di satu tempat, di-query banyak cara" ini persis kayak yang dibahas di artikel Arsitektur LTAP: Postgres + Parquet + S3 — satu fondasi data, banyak paradigma akses.
Install DuckPGQ di DuckDB
Instalasinya gak nyusahin — satu baris INSTALL, satu baris LOAD. Gak ada server, gak ada port, gak ada daemon yang jalan di background:
INSTALL duckpgq; LOAD duckpgq; di client SQL, duckdb -c "INSTALL duckpgq; LOAD duckpgq;" dari CLI, atau dari Python: con.execute("INSTALL duckpgq; LOAD duckpgq;").
Perlu dicatat: DuckPGQ adalah community extension, bukan bagian dari rilis resmi DuckDB. Artinya di versi DuckDB tertentu mungkin perlu install dari community repository dulu — cek halaman resminya di duckpgq.org buat instruksi versi terkini. Setelah extension ke-load, sintaks SQL/PGQ langsung dikenali.
Kalau mau jalanin DuckDB dalam mode server biar satu database bisa diakses tim (bukan cuma lokal di laptop), butuh VPS yang murah tapi reliable. RackNerd lumayan populer buat ini — mulai dari harga murah per tahun, udah kebukti stabil buat workload analitis skala menengah.
Bikin Property Graph dari Tabel Biasa
Oke, sekarang praktik. Anggap ada data jejaring sosial sederhana dalam dua tabel DuckDB biasa — gak ada yang spesial, ini tabel normal yang bisa diisi dari CSV, Parquet, atau hasil ETL:
CREATE TABLE users (
user_id BIGINT PRIMARY KEY,
username TEXT NOT NULL,
created_at TIMESTAMPTZ
);
CREATE TABLE friendships (
user_a BIGINT NOT NULL,
user_b BIGINT NOT NULL,
since DATE,
PRIMARY KEY (user_a, user_b)
);
INSERT INTO users VALUES
(1, 'alice', '2024-01-15'), (2, 'bob', '2024-02-20'),
(3, 'carol', '2024-03-10'), (4, 'dave', '2024-03-15'),
(5, 'eve', '2024-04-22');
INSERT INTO friendships VALUES
(1, 2, '2024-03-01'), (1, 3, '2024-04-15'),
(2, 4, '2024-05-01'), (3, 5, '2024-06-01'),
(4, 5, '2024-06-15');
-- Deklarasi property graph: node = users, edge = friendships
CREATE PROPERTY GRAPH social_network
VERTEX TABLES (
users PROPERTIES (user_id, username, created_at)
)
EDGE TABLES (
friendships
SOURCE KEY (user_a) REFERENCES users (user_id)
DESTINATION KEY (user_b) REFERENCES users (user_id)
PROPERTIES (since)
);
Itu doang. Mulai sekarang, social_network adalah graph yang bisa di-query — padahal data fisiknya tetap dua tabel biasa.
Query Dua-Hop: Temen dari Temen
Contoh klasik: cari semua temen dari temennya user 1 (two-hop traversal). Di SQL biasa ini butuh self-join dua kali; dengan SQL/PGQ pattern matching-nya ditulis langsung:
SELECT c.username, COUNT(*) AS mutual_friends
FROM GRAPH_TABLE(social_network
MATCH (a IS users)-[IS friendships]->(b IS users)-[IS friendships]->(c IS users)
WHERE a.user_id = 1 AND c.user_id != 1
COLUMNS (c.username)
) AS two_hop
GROUP BY c.username
ORDER BY mutual_friends DESC;
Baca syntax-nya gampang: MATCH (a)-[...]->(b)-[...]->(c) itu artinya "cari jalur dari a ke b ke c lewat edge friendships". Hasilnya tabel biasa — bisa di-join, di-group, atau dilanjut ke analytical query lain. Itu poin pentingnya: graph query di DuckPGQ gak ngeluarin "hasil graph", tapi baris-baris data yang bisa diproses kayak biasa.
Fraud Detection: Cari Chain 3-Hop
Use case yang paling sering dipake orang: fraud detection. Pola umumnya gini — dua akun yang kelihatannya independen ternyata nyambung lewat rantai transfer yang mencurigakan. Query 3-hop kayak gini:
CREATE TABLE accounts (
account_id BIGINT PRIMARY KEY,
holder_name TEXT,
country TEXT,
opened_at DATE
);
CREATE TABLE transfers (
transfer_id BIGINT PRIMARY KEY,
from_account BIGINT,
to_account BIGINT,
amount NUMERIC(15, 2),
transferred_at TIMESTAMPTZ
);
CREATE PROPERTY GRAPH financial
VERTEX TABLES (accounts)
EDGE TABLES (
transfers
SOURCE KEY (from_account) REFERENCES accounts
DESTINATION KEY (to_account) REFERENCES accounts
PROPERTIES (amount, transferred_at)
);
-- Cari semua chain 3-hop antara account 1001 dan 2002 dalam 30 hari terakhir
SELECT path, total_amount
FROM GRAPH_TABLE(financial
MATCH (a)-[t1:transfers]->(b)-[t2:transfers]->(c)-[t3:transfers]->(d)
WHERE a.account_id = 1001 AND d.account_id = 2002
AND t1.transferred_at > NOW() - INTERVAL '30 days'
COLUMNS (
LIST(t1.transfer_id, t2.transfer_id, t3.transfer_id) AS path,
t1.amount + t2.amount + t3.amount AS total_amount
)
);
Query yang sama di SQL murni butuh recursive CTE yang panjang dan susah dibaca. Di sini keliatan gimana edge properties (amount, transferred_at) ikut ke-filter dan ke-agregasi langsung di pattern — ini yang bikin SQL/PGQ kerasa lebih natural buat analisis semacem ini.
Integrasi Python: Pandas & Polars
Kalau workflow berbasis notebook atau script Python (data scientist banget), DuckPGQ nempel natural banget. Data di DataFrame, graph query jalan di atasnya, hasilnya balik lagi jadi DataFrame:
import duckdb
import pandas as pd
con = duckdb.connect()
con.execute("INSTALL duckpgq; LOAD duckpgq;")
# Load data dari Parquet langsung
users_df = pd.read_parquet("users.parquet")
friends_df = pd.read_parquet("friendships.parquet")
con.register("users", users_df)
con.register("friendships", friends_df)
# Deklarasi graph + jalankan query, hasil balik jadi DataFrame
result_df = con.execute("""
CREATE PROPERTY GRAPH social AS
VERTEX TABLES (users)
EDGE TABLES (friendships
SOURCE KEY (user_a) REFERENCES users (user_id)
DESTINATION KEY (user_b) REFERENCES users (user_id));
SELECT * FROM GRAPH_TABLE(social
MATCH (a)-[e]->(b)
COLUMNS (a.username, b.username, e.since)
);
""").df()
print(result_df.head())
Gak perlu ETL ke database graph terpisah, gak perlu adapter khusus — analisis graph jalan di tempat data udah berada. Buat yang suka explore data kayak gini, ini level nyaman yang sulit ditandingin database graph tradisional.
DuckPGQ vs Neo4j: Perbandingan Jujur
Biar gak ada salah kaprah: DuckPGQ bukan pengganti Neo4j. Dua-duanya punya posisi yang beda. Ini perbandingannya:
| Aspek | DuckPGQ (DuckDB) | Neo4j / Graph DB Khusus |
|---|---|---|
| Instalasi | 1 baris INSTALL extension | Server sendiri, sizing memory, monitoring |
| Bahasa query | SQL/PGQ + subset Cypher | Cypher lengkap |
| Workload ideal | Batch analytics, prototyping, ETL | Transaksional + traversal real-time |
| Graph mutations | Gak fokus (OLAP read-heavy) | Jago banget (OLTP) |
| Algoritma graph | Perlu extension/user-defined | Built-in (PageRank, centrality, dsb) |
| Multi-user & ACL | Terbatas | Mature, enterprise-grade |
| Biaya operasional | Nol tambahan — jalan di infra yang ada | License + kompleksitas ops |
Intinya: kalau kebutuhan analitis dan batch, DuckPGQ biasanya udah cukup — dan gratis dari segi overhead. Kalau butuh transaksi graph real-time dengan jutaan mutation per detik dan ACL ketat, barulah database graph khusus masuk akal.
Kapan Pilih DuckPGQ, Kapan Enggak
Biar makin jelas, ini checklist praktisnya:
✅ DuckPGQ pas dipake kalau:
- Query graph jalan sebagai batch job atau pipeline ETL, bukan real-time
- Tim udah nyaman DuckDB dan gak mau nambah database baru
- Volume data menengah — ratusan juta edge masih aman
- Masih prototyping dan belum yakin butuh database graph khusus
- Pengen generate graph features buat model ML langsung dari data warehouse
❌ Skip DuckPGQ, pilih database graph khusus kalau:
- Traversal real-time dengan latency super rendah (di bawah puluhan ms)
- Graph miliaran edge dan butuh distributed processing
- Butuh suite algoritma graph lengkap (community detection, centrality) tanpa setup tambahan
- Kebutuhan multi-user dengan isolation dan access control yang kompleks
Pattern Efektif: Materialisasi Adjacency List
Satu pola yang sering dipake di production: buat dataset gede, materialisasi adjacency list dulu, baru query di atasnya. Kedengeran kontradiktif (kok di-materialisasi?), tapi justru ini yang manfaatin kekuatan DuckDB — columnar scan yang cepet:
-- Materialisasi adjacency list (termasuk edge dua arah)
CREATE TABLE adjacency AS
SELECT user_a AS source, user_b AS target FROM friendships
UNION ALL
SELECT user_b, user_a FROM friendships;
-- Query friend-of-friend pake JOIN biasa
SELECT DISTINCT t2.target
FROM adjacency t1
JOIN adjacency t2 ON t1.target = t2.source
WHERE t1.source = 1 AND t2.target != 1;
Untuk pattern matching yang sederhana, JOIN tiga-tahap kayak gini sering secepat DuckPGQ — dan query plan-nya lebih predictable. DuckPGQ baru menang telak kalau pattern-nya kompleks: variable-length path, optional match, atau filter di edge properties yang susah diekspresikan di SQL biasa. Jadi bukan "salah satu harus menang", tapi pilih alat sesuai bentuk query-nya.
Graph Sering Berubah? Manfaatin Time Travel
Graph di dunia nyata gak statis — tiap hari ada edge baru. Pola yang efektif di sini: versioning graph dengan valid-from/valid-to, terus query di snapshot tertentu. DuckDB punya dukungan time travel yang bikin ini natural:
SELECT * FROM GRAPH_TABLE(social_network MATCH (a)-[r]->(b) WHERE r.valid_from <= '2026-07-25' AND r.valid_to > '2026-07-25' COLUMNS (a.username, b.username));
Dengan pola ini, analisis historis ("kondisi graph seminggu yang lalu kayak gimana?") bisa jalan tanpa rebuild graph per query. Buat audit trail atau analisis tren, ini senjata yang jarang dimiliki database graph tradisional.
Performance Reality Check
Jujur soal performa: untuk traversal 2–4 hop di dataset sampai ratusan juta edge, DuckPGQ sebanding dengan Neo4j — kadang malah lebih cepet di pattern matching yang kompleks, karena execution columnar DuckDB yang mature. Tapi untuk algoritma iterative kayak PageRank atau connected components, database graph khusus biasanya unggul karena implementasinya dioptimasi spesifik buat algoritma itu. Dan untuk graph mutations, Neo4j jelas menang — arsitektur DuckDB emang read-oriented OLAP, bukan buat write-heavy.
Buat angka benchmark yang lebih detail, cek repository dan dokumentasi resmi DuckPGQ — benchmark komunitas-nya update dan transparan soal metodologi-nya.
Roadmap & Ekosistem
DuckPGQ masih aktif dikembangin — ini bukan proyek mati. Coverage SQL/PGQ terus ngejar standar ISO SQL:2023, subset Cypher-nya nambah terus, dan ekosistem DuckDB lagi nyiapin extension terpisah buat graph algorithms yang kerja bareng DuckPGQ sebagai graph provider. Dukungan institusionalnya kuat: dikembangin di CWI (institusi riset), dipakai secara internal oleh perusahaan-perusahaan yang butuh graph analytics tanpa overhead database terpisah, dan punya 460+ stars di GitHub dengan lisensi MIT.
Buat yang penasaran sama arah analytics modern, ekosistem ini satu paket menarik — baca juga artikel soal Trifle, analytics open-source yang simpan jawaban bukan events, satu lagi contoh tools yang nge-simplify stack data.
Komunitas & Cara Bisa Kontribusi
DuckPGQ dikembangin terbuka: kontribusi datang dari akademisi, engineer industri, dan kontributor independen. Issue tracker-nya responsif, roadmap-nya transparan, dan diskusi jalan di Discord DuckDB. Area yang paling butuh bantuan: dokumentasi (terutama use case advanced), test coverage (edge case pattern matching), dan integrasi ekosistem Python (adapter NetworkX, integrasi Pandas yang lebih dalam).
Selain nambah ilmu, kontribusi ke proyek kayak gini adalah cara paling efektif buat bener-bener paham graph database dan query optimization — belajar sambil nge-fix issue itu beda level sama baca tutorial.
Kesimpulan
DuckPGQ itu bukti kalau evolusi tooling data masih kencang banget. Kemampuan yang dulu cuma ada di database graph khusus yang berat sekarang bisa diakses sebagai extension dari database yang udah umum dipake — lebih banyak pilihan, lebih sedikit lock-in, lebih fleksibel milih tool sesuai kebutuhan. Untuk profesional data yang sering nge-trade-off antara tooling simpel dan kemampuan powerful, ini kabar bagus.
Kalau butuh VPS murah buat self-host stack analitis (DuckDB server, pipeline, dashboard), cek RackNerd — cocok buat workload batch kayak gini tanpa ngerogoh kocek dalem-dalem.
💬 Komentar (0)
Belum ada komentar. Jadilah yang pertama! 💬