Ringkasan kueri grafik

BigQuery Graph memungkinkan Anda menulis kueri graf untuk mencocokkan pola node, edge, dan jalur serta melintasi hubungan menggunakan Graph Query Language (GQL). Contoh dalam dokumen ini mengacu pada grafik yang disebut FinGraph, yang menunjukkan hubungan antara orang, akun yang mereka miliki, dan transfer antar- akun. Untuk mengetahui informasi tentang definisi grafik, lihat contoh FinGraph.

Struktur kueri

Kueri grafik terdiri dari nama grafik, diikuti dengan satu atau beberapa pernyataan kueri linear. Setiap kueri linear berisi satu atau beberapa pernyataan, yang memungkinkan Anda menggunakan data grafik untuk menemukan kecocokan pola, menentukan variabel, memfilter dan mentransformasi data perantara, serta menampilkan hasil. Anda menjalankan kueri grafik dengan cara yang sama seperti menjalankan kueri SQL di BigQuery.

Contoh struktur kueri grafik.
Contoh struktur kueri grafik.

Pencocokan pola grafik

Pencocokan pola grafik menemukan pola tertentu dalam grafik Anda. Pola yang paling dasar adalah pola elemen, seperti pola node yang cocok dengan node dan pola edge yang cocok dengan edge.

Pola node

Pola node mencocokkan node dalam grafik Anda. Pola ini berisi tanda kurung yang cocok, yang dapat menyertakan variabel pola grafik, ekspresi label, dan filter properti.

Menemukan semua node

Kueri berikut menampilkan semua node dalam grafik. Variabel n, variabel pola grafik, mengikat ke node yang cocok. Dalam hal ini, pola node cocok dengan semua node dalam grafik.

GRAPH graph_db.FinGraph
MATCH (n)
RETURN LABELS(n) AS label, n.id;

Kueri ini menampilkan label dan id:

label id
Account 7
Account 16
Account 20
Person 1
Person 2
Person 3

Menemukan semua node dengan label tertentu

Kueri berikut mencocokkan semua node dalam grafik yang memiliki label Person. Kueri menampilkan label dan beberapa properti node yang cocok.

GRAPH graph_db.FinGraph
MATCH (p:Person)
RETURN LABELS(p) AS label, p.id, p.name;

Kueri ini menampilkan properti node yang cocok berikut:

label id name
Person 1 Alex
Person 2 Dana
Person 3 Lee

Menemukan semua node yang cocok dengan ekspresi label

Anda dapat membuat ekspresi label dengan satu atau beberapa operator logika. Misalnya, kueri berikut mencocokkan semua node dalam grafik yang memiliki label Person atau Account. Variabel pola grafik n mengekspos semua properti dari node dengan label Person atau Account.

GRAPH graph_db.FinGraph
MATCH (n:Person|Account)
RETURN LABELS(n) AS label, n.id, n.birthday, n.create_time;

Perhatikan hal berikut dalam hasil kueri ini:

  • Semua node memiliki properti id.
  • Node yang cocok dengan label Account memiliki properti create_time, tetapi tidak memiliki properti birthday. Properti birthday adalah NULL untuk node ini.
  • Node yang cocok dengan label Person memiliki properti birthday, tetapi tidak memiliki properti create_time. Properti create_time adalah NULL untuk node ini.
label id birthday create_time
Account 7 NULL 2020-01-10T14:22:20.222Z
Account 16 NULL 2020-01-28T01:55:09.206Z
Account 20 NULL 2020-02-18T13:44:20.655Z
Person 1 1991-12-21T08:00:00Z NULL
Person 2 1980-10-31T08:00:00Z NULL
Person 3 1986-12-07T08:00:00Z NULL

Menemukan semua node yang cocok dengan ekspresi label dan filter properti

Kueri berikut mencocokkan semua node dalam grafik yang memiliki label Person dan properti id yang sama dengan 1:

GRAPH graph_db.FinGraph
MATCH (p:Person {id: 1})
RETURN LABELS(p) AS label, p.id, p.name, p.birthday;

Hasilnya mirip dengan berikut ini:

label id name birthday
Person 1 Alex 1991-12-21T08:00:00Z

Anda dapat menggunakan klausa WHERE untuk membentuk kondisi pemfilteran yang lebih kompleks pada label dan properti.

Kueri berikut menggunakan klausa WHERE untuk memfilter node yang properti birthday-nya sebelum 1990-01-10:

GRAPH graph_db.FinGraph
MATCH (p:Person WHERE p.birthday < '1990-01-10')
RETURN LABELS(p) AS label, p.name, p.birthday;

Hasilnya mirip dengan berikut ini:

label name birthday
Person Dana 1980-10-31T08:00:00Z
Person Lee 1986-12-07T08:00:00Z

Pola edge

Pola edge mencocokkan edge atau hubungan antar-node. Pola edge diapit dalam tanda kurung siku ([]) dan menyertakan simbol seperti -, ->, atau <- untuk menunjukkan arah. Pola edge dapat secara opsional menyertakan variabel pola grafik untuk mengikat ke edge yang cocok.

Menemukan semua edge dengan label yang cocok

Kueri ini menampilkan semua edge dalam grafik dengan label Transfers. Kueri mengikat variabel pola grafik e ke tepi yang cocok.

GRAPH graph_db.FinGraph
MATCH -[e:Transfers]->
RETURN e.Id as src_account, e.order_number;

Hasilnya mirip dengan berikut ini:

src_account order_number
7 304330008004315
7 304120005529714
16 103650009791820
20 304120005529714
20 302290001255747

Menemukan semua edge yang cocok dengan ekspresi label dan filter properti

Pola edge dalam kueri berikut menggunakan ekspresi label dan filter properti untuk menemukan semua edge berlabel Transfers yang cocok dengan nomor pesanan yang ditentukan:

GRAPH graph_db.FinGraph
MATCH -[e:Transfers {order_number: "304120005529714"}]->
RETURN e.Id AS src_account, e.order_number;

Hasilnya mirip dengan berikut ini:

src_account order_number
7 304120005529714
20 304120005529714

Menemukan semua tepi menggunakan pola tepi arah apa pun

Anda dapat menggunakan pola edge any direction (-[]-) dalam kueri untuk mencocokkan edge di kedua arah. Kueri berikut menemukan semua transfer dengan akun yang diblokir:

GRAPH graph_db.FinGraph
MATCH (account:Account)-[transfer:Transfers]-(:Account {is_blocked:true})
RETURN transfer.order_number, transfer.amount;

Hasilnya mirip dengan berikut ini:

order_number amount
304330008004315 300
304120005529714 100
103650009791820 300
302290001255747 200

Pola jalur

Pola jalur dibuat dari pola node dan edge yang bergantian.

Menemukan semua jalur dari node tertentu menggunakan pola jalur

Kueri berikut menemukan semua transfer ke akun yang dimulai dari akun yang dimiliki oleh Person dengan id sama dengan 2.

Setiap hasil yang cocok mewakili jalur dari node Person saat id sama dengan 2 melalui node Account yang terhubung menggunakan edge Owns, ke node Account lain menggunakan edge Transfers.

GRAPH graph_db.FinGraph
MATCH
  (p:Person {id: 2})-[:Owns]->(account:Account)-[t:Transfers]->
  (to_account:Account)
RETURN
  p.id AS sender_id, account.id AS from_id, to_account.id AS to_id;

Hasilnya mirip dengan berikut ini:

sender_id from_id to_id
2 20 7
2 20 16

Pola jalur terukur

Pola terkuantifikasi mengulangi pola dalam rentang yang ditentukan.

Mencocokkan pola tepi yang dikuantifikasi

Untuk menemukan jalur dengan panjang variabel, Anda dapat menerapkan pengukur ke pola edge. Kueri berikut menunjukkan hal ini dengan menemukan akun tujuan yang berjarak satu hingga tiga transfer dari Account sumber dengan nilai id 7.

Kueri menerapkan pengukur {1, 3} ke pola edge -[e:Transfers]->. Tindakan ini akan menginstruksikan kueri untuk mencocokkan jalur yang mengulangi pola edge Transfers satu, dua, atau tiga kali. Klausa WHERE digunakan untuk mengecualikan akun sumber dari hasil. Fungsi ARRAY_LENGTH digunakan untuk mengakses group variable e.

GRAPH graph_db.FinGraph
MATCH (src:Account {id: 7})-[e:Transfers]->{1, 3}(dst:Account)
WHERE src != dst
RETURN src.id AS src_account_id, ARRAY_LENGTH(e) AS path_length, dst.id AS dst_account_id;

Hasilnya mirip dengan berikut ini:

src_account_id path_length dst_account_id
7 1 16
7 1 16
7 3 16
7 3 16
7 2 20
7 2 20

Beberapa baris dalam hasil diulang. Hal ini karena beberapa jalur yang cocok dengan pola dapat ada di antara node sumber dan tujuan yang sama, dan kueri akan menampilkan semuanya.

Mencocokkan pola jalur yang dihitung

Kueri berikut menemukan jalur antara node Account dengan satu hingga dua edge Transfers melalui akun perantara yang diblokir.

Pola jalur dalam tanda kurung dihitung, dan klausa WHERE-nya menentukan kondisi untuk pola berulang.

GRAPH graph_db.FinGraph
MATCH
  (src:Account)
  ((a:Account)-[:Transfers]->(b:Account {is_blocked:true}) WHERE a != b){1,2}
    -[:Transfers]->(dst:Account)
RETURN src.id AS src_account_id, dst.id AS dst_account_id;

Hasilnya mirip dengan berikut ini:

src_account_id dst_account_id
7 20
7 20
20 20

Variabel grup

Variabel pola grafik yang dideklarasikan dalam pola yang dikuantifikasi menjadi variabel grup saat diakses di luar pola tersebut. Kemudian, fungsi ini mengikat ke array elemen grafik yang cocok.

Anda dapat mengakses variabel grup sebagai array. Elemen grafiknya dipertahankan sesuai urutan kemunculannya di sepanjang jalur yang cocok. Anda dapat menggabungkan variabel grup menggunakan agregasi horizontal.

Variabel grup akses

Dalam contoh berikut, variabel e diakses sebagai berikut:

  • Sebagai variabel pola grafik yang terikat ke satu edge dalam klausa WHERE e.amount > 100 saat berada dalam pola yang dikuantifikasi.
  • Sebagai variabel grup yang terikat ke array elemen edge di ARRAY_LENGTH(e) dalam pernyataan RETURN saat berada di luar pola yang dikuantifikasi.
  • Sebagai variabel grup yang terikat ke array elemen edge, yang digabungkan oleh SUM(e.amount) di luar pola yang diukur. Ini adalah contoh agregasi horizontal.
GRAPH graph_db.FinGraph
MATCH
  (src:Account {id: 7})-[e:Transfers WHERE e.amount > 100]->{0,2}
  (dst:Account)
WHERE src.id != dst.id
LET total_amount = SUM(e.amount)
RETURN
  src.id AS src_account_id, ARRAY_LENGTH(e) AS path_length,
  total_amount, dst.id AS dst_account_id;

Hasilnya mirip dengan berikut ini:

src_account_id path_length total_amount dst_account_id
7 1 300 16
7 2 600 20

Awalan penelusuran jalur

Untuk membatasi jalur yang cocok dalam grup yang memiliki node sumber dan tujuan yang sama, Anda dapat menggunakan awalan penelusuran jalur ANY, ANY SHORTEST, atau ANY CHEAPEST. Anda hanya dapat menerapkan awalan ini sebelum seluruh pola jalur, dan Anda tidak dapat menerapkannya di dalam tanda kurung.

Cocokkan menggunakan ANY

Kueri berikut menemukan semua akun unik yang dapat dijangkau yang berjarak satu atau dua Transfers dari node Account tertentu.

Awalan penelusuran jalur ANY memastikan bahwa kueri hanya menampilkan satu jalur antara pasangan unik node src dan dst Account. Dalam contoh berikut, meskipun Anda dapat menjangkau node Account dengan {id: 16} dalam dua jalur berbeda dari node Account sumber, kueri hanya menampilkan satu jalur.

GRAPH graph_db.FinGraph
MATCH ANY (src:Account {id: 7})-[e:Transfers]->{1,2}(dst:Account)
LET ids_in_path = ARRAY_CONCAT(ARRAY_AGG(e.Id), [dst.Id])
RETURN src.id AS src_account_id, dst.id AS dst_account_id, ids_in_path;

Hasilnya mirip dengan berikut ini:

src_account_id dst_account_id ids_in_path
7 16 7,16
7 20 7,16,20

Cocokkan menggunakan ANY SHORTEST

Awalan penelusuran jalur ANY SHORTEST menampilkan satu jalur untuk setiap pasangan node sumber dan tujuan, yang dipilih dari node dengan jumlah edge minimum.

Misalnya, kueri berikut menemukan salah satu jalur terpendek antara node Account dengan nilai id dari 7 dan node Account dengan nilai id dari 20. Kueri ini mempertimbangkan jalur dengan satu hingga tiga tepi Transfers.

GRAPH graph_db.FinGraph
MATCH ANY SHORTEST (src:Account {id: 7})-[e:Transfers]->{1, 3}(dst:Account {id: 20})
RETURN src.id AS src_account_id, dst.id AS dst_account_id, ARRAY_LENGTH(e) AS path_length;

Hasilnya mirip dengan berikut ini:

src_account_id dst_account_id path_length
7 20 2

Cocokkan menggunakan ANY CHEAPEST

Awalan penelusuran jalur ANY CHEAPEST memastikan bahwa untuk setiap pasangan akun sumber dan tujuan, kueri hanya menampilkan satu jalur dengan total biaya komputasi minimum.

Kueri berikut menemukan jalur dengan total biaya komputasi minimum antara node Account. Biaya ini didasarkan pada jumlah properti amount dari edge Transfers. Penelusuran mempertimbangkan jalur dengan satu hingga tiga edge Transfers.

GRAPH graph_db.FinGraph
MATCH ANY CHEAPEST (src:Account)-[e:Transfers COST e.amount]->{1,3}(dst:Account)
LET total_cost = sum(e.amount)
RETURN src.id AS src_account_id, dst.id AS dst_account_id, total_cost;

Hasilnya mirip dengan berikut ini:

src_account_id dst_account_id total_cost
7 7 900
7 16 100
7 20 400
16 7 800
16 16 500
16 20 300
20 7 500
20 16 200
20 20 500

Pola grafik

Pola grafik terdiri dari satu atau beberapa pola jalur, yang dipisahkan dengan koma (,). Pola grafik dapat berisi klausa WHERE, yang memungkinkan Anda mengakses semua variabel pola grafik dalam pola jalur untuk membentuk kondisi pemfilteran. Setiap pola jalur menghasilkan kumpulan jalur.

Mencocokkan menggunakan pola grafik

Kueri berikut mengidentifikasi akun perantara dan pemiliknya yang terlibat dalam jumlah transaksi yang melebihi 200, yang digunakan untuk mentransfer dana dari akun sumber ke akun yang diblokir.

Pola jalur berikut membentuk pola grafik:

  • Pola pertama menemukan jalur tempat transfer terjadi dari satu akun ke akun yang diblokir menggunakan akun perantara.
  • Pola kedua menemukan jalur dari akun ke orang yang memilikinya.

Variabel interm bertindak sebagai link umum antara dua pola jalur, yang mengharuskan interm mereferensikan node elemen yang sama di kedua pola jalur. Tindakan ini membuat operasi equi-join berdasarkan variabel interm.

GRAPH graph_db.FinGraph
MATCH
  (src:Account)-[t1:Transfers]->(interm:Account)-[t2:Transfers]->(dst:Account),
  (interm)<-[:Owns]-(p:Person)
WHERE dst.is_blocked = TRUE AND t1.amount > 200 AND t2.amount > 200
RETURN
  src.id AS src_account_id, dst.id AS dst_account_id,
  interm.id AS interm_account_id, p.id AS owner_id;

Hasilnya mirip dengan berikut ini:

src_account_id dst_account_id interm_account_id owner_id
20 16 7 1

Pernyataan kueri linear

Anda dapat merangkai beberapa pernyataan grafik bersama-sama untuk membentuk pernyataan kueri linear. Pernyataan dieksekusi dalam urutan yang sama seperti yang muncul dalam kueri.

  • Setiap pernyataan mengambil output dari pernyataan sebelumnya sebagai input. Input kosong untuk pernyataan pertama.

  • Output dari pernyataan terakhir adalah hasil akhir.

Misalnya, Anda dapat menggunakan pernyataan kueri linear untuk menemukan transfer maksimum ke akun yang diblokir. Kueri berikut menemukan akun dan pemiliknya dengan transfer keluar terbesar ke akun yang diblokir.

GRAPH graph_db.FinGraph
MATCH (src_account:Account)-[transfer:Transfers]->(dst_account:Account {is_blocked:true})
ORDER BY transfer.amount DESC
LIMIT 1
MATCH (src_account:Account)<-[owns:Owns]-(owner:Person)
RETURN src_account.id AS account_id, owner.name AS owner_name;

Tabel berikut mengilustrasikan proses ini dengan menampilkan hasil perantara yang diteruskan di antara setiap pernyataan. Agar lebih singkat, hanya beberapa properti yang ditampilkan.

Pernyataan Hasil menengah (disingkat)
MATCH
  (src_account:Account)
    -[transfer:Transfers]->
  (dst_account:Account {is_blocked:true})
src_account transfer dst_account
{id: 7} {amount: 300.0} {id: 16, is_blocked: true}
{id: 7} {amount: 100.0} {id: 16, is_blocked: true}
{id: 20} {amount: 200.0} {id: 16, is_blocked: true}

ORDER BY transfer.amount DESC
src_account transfer dst_account
{id: 7} {amount: 300.0} {id: 16, is_blocked: true}
{id: 20} {amount: 200.0} {id: 16, is_blocked: true}
{id: 7} {amount: 100.0} {id: 16, is_blocked: true}

LIMIT 1
src_account transfer dst_account
{id: 7} {amount: 300.0} {id: 16, is_blocked: true}

MATCH
  (src_account:Account)
    <-[owns:Owns]-
  (owner:Person)
src_account transfer dst_account memiliki owner
{id: 7} {amount: 300.0} {id: 16, is_blocked: true} {person_id: 1, account_id: 7} {id: 1, name: Alex}
RETURN
  src_account.id AS account_id,
  owner.name AS owner_name
        
account_id owner_name
7 Alex

Hasilnya mirip dengan berikut ini:

account_id owner_name
7 Alex

Pernyataan return

Pernyataan RETURN menentukan apa yang akan ditampilkan dari pola yang cocok. Subkueri ini dapat mengakses variabel pola grafik serta menyertakan ekspresi dan klausa lainnya, seperti ORDER BY dan GROUP BY.

BigQuery Graph tidak mendukung pengembalian elemen grafik sebagai hasil kueri. Untuk menampilkan seluruh elemen grafik, gunakan fungsi TO_JSON.

Menampilkan elemen grafik sebagai JSON

GRAPH graph_db.FinGraph
MATCH (n:Account {id: 7})
-- Returning a graph element in the final results is NOT allowed. Instead, use
-- the TO_JSON function or explicitly return the graph element's properties.
RETURN TO_JSON(n) AS n;

Hasilnya mirip dengan berikut ini:

n
{"identifier":"mUZpbkdyYXBoLkFjY291bnQAeJEO","kind":"node","labels":["Account"],"properties":{"create_time":"2020-01-10T14:22:20.222Z","id":7,"is_blocked":false,"nick_name":"Vacation Fund"}}

Menulis kueri yang lebih besar dengan kata kunci NEXT

Anda dapat merangkai beberapa pernyataan kueri linear grafik menggunakan kata kunci NEXT. Pernyataan pertama menerima input kosong, dan output dari setiap pernyataan berikutnya menjadi input untuk pernyataan berikutnya.

Contoh berikut menemukan pemilik akun dengan transfer masuk terbanyak dengan merangkai beberapa pernyataan linear grafik. Anda dapat menggunakan variabel yang sama, misalnya, account, untuk merujuk ke elemen grafik yang sama di beberapa pernyataan linear.

GRAPH graph_db.FinGraph
MATCH (:Account)-[:Transfers]->(account:Account)
RETURN account, COUNT(*) AS num_incoming_transfers
GROUP BY account
ORDER BY num_incoming_transfers DESC
LIMIT 1

NEXT

MATCH (account:Account)<-[:Owns]-(owner:Person)
RETURN account.id AS account_id, owner.name AS owner_name, num_incoming_transfers;

Hasilnya mirip dengan berikut ini:

account_id owner_name num_incoming_transfers
16 Lee 3

Anda juga dapat menggabungkan pernyataan kueri linear dengan operator set.

Fungsi dan ekspresi

Anda dapat menggunakan semua fungsi GoogleSQL (fungsi agregat dan skalar), operator, dan ekspresi bersyarat dalam kueri grafik. BigQuery Graph juga mendukung fungsi GQL dan operator GQL yang hanya dapat digunakan dalam kueri grafik.

Kueri berikut menyertakan campuran fungsi dan operator GQL dan SQL dalam kueri grafik:

GRAPH graph_db.FinGraph
MATCH (person:Person)-[o:Owns]->(account:Account)
WHERE person IS SOURCE OF o
RETURN person, ARRAY_AGG(account.nick_name) AS accounts
GROUP BY person

NEXT

RETURN
  LABELS(person) AS labels,
  accounts,
  CONCAT(person.city, ", ", person.country) AS location,
  TO_JSON(person) AS person
LIMIT 1;

Hasilnya mirip dengan berikut ini:

labels akun lokasi pengguna
Person ["Vacation Fund"] Adelaide, Australia {"identifier":"mUZpbkdyYXBoLlBlcnNvbgB4kQI=","kind":"node","labels":["Person"],"properties":{"birthday":"1991-12-21T08:00:00Z","city":"Adelaide","country":"Australia","id":1,"name":"Alex"}}

Subkueri

Subkueri adalah kueri yang disusun bertingkat dalam kueri lain. Aturan berikut berlaku untuk subkueri dalam kueri grafik:

  • Subkueri diapit dalam sepasang tanda kurung kurawal {}.
  • Subkueri dimulai dengan klausa GRAPH untuk menentukan grafik dalam cakupan. Grafik yang ditentukan tidak harus sama dengan yang digunakan dalam kueri luar.
  • Variabel pola grafik yang dideklarasikan di luar cakupan subkueri tidak dapat dideklarasikan lagi di dalam subkueri, tetapi dapat dirujuk dalam ekspresi atau fungsi di dalam subkueri.

Menggunakan subkueri untuk menemukan jumlah total transfer dari setiap akun

Kueri berikut mengilustrasikan penggunaan subkueri VALUE. Subkueri diapit dalam tanda kurung kurawal {} yang diawali dengan kata kunci VALUE. Kueri tersebut menampilkan jumlah total transfer yang dimulai dari sebuah akun.

GRAPH graph_db.FinGraph
MATCH (p:Person)-[:Owns]->(account:Account)
RETURN p.name, account.id AS account_id, VALUE {
  GRAPH graph_db.FinGraph
  MATCH (a:Account)-[transfer:Transfers]->(:Account)
  WHERE a = account
  RETURN COUNT(transfer) AS num_transfers
} AS num_transfers;

Hasilnya mirip dengan berikut ini:

nama account_id num_transfers
Alex 7 2
Dana 20 2
Lee 16 1

Untuk mengetahui daftar ekspresi subkueri yang didukung, lihat Subkueri BigQuery Graph.

Parameter kueri

Anda dapat membuat kueri BigQuery Graph dengan parameter. Untuk mengetahui informasi selengkapnya, lihat sintaksis dan pelajari cara Menjalankan kueri berparameter.

Kueri berikut cocok dengan node Person yang memiliki nilai id yang cocok dengan parameter kueri:

GRAPH graph_db.FinGraph
MATCH (person:Person {id: @id})
RETURN person.name;

Membuat kueri grafik dan tabel secara bersamaan

Anda dapat menggabungkan kueri grafik dan kueri SQL menggunakan operator GRAPH_TABLE.

Operator GRAPH_TABLE mengambil kueri grafik linear dan menampilkan hasilnya dalam bentuk tabel yang dapat diintegrasikan ke dalam kueri SQL. Interoperabilitas ini memungkinkan Anda memperkaya hasil kueri grafik dengan konten non-grafik dan sebaliknya.

Misalnya, Anda dapat membuat tabel CreditReports dan menyisipkan beberapa laporan kredit, seperti yang ditunjukkan dalam contoh berikut:

CREATE TABLE graph_db.CreditReports (
  person_id     INT64 NOT NULL,
  create_time   TIMESTAMP NOT NULL,
  score         INT64 NOT NULL,
  PRIMARY KEY (person_id, create_time) NOT ENFORCED
);
INSERT INTO graph_db.CreditReports (person_id, create_time, score)
VALUES
  (1,"2020-01-10 06:22:20.222", 700),
  (2,"2020-02-10 06:22:20.222", 800),
  (3,"2020-03-10 06:22:20.222", 750);

Selanjutnya, Anda dapat mengidentifikasi orang tertentu melalui pencocokan pola grafik di GRAPH_TABLE dan menggabungkan hasil kueri grafik dengan tabel CreditReports untuk mengambil skor kredit.

SELECT
  gt.person.id,
  credit.score AS latest_credit_score
FROM GRAPH_TABLE(
  graph_db.FinGraph
  MATCH (person:Person)-[:Owns]->(:Account)-[:Transfers]->(account:Account {is_blocked:true})
  RETURN DISTINCT person
) AS gt
JOIN graph_db.CreditReports AS credit
  ON gt.person.id = credit.person_id
ORDER BY credit.create_time;

Hasilnya mirip dengan berikut ini:

person_id latest_credit_score
1 700
2 800

Praktik terbaik

Anda dapat mengoptimalkan performa kueri dengan menyusun kueri GQL untuk meminimalkan jumlah data yang dipindai dan jumlah hasil perantara.

Memulai penjelajahan jalur dari node kardinalitas rendah

Agar set hasil perantara tetap kecil dan mempercepat eksekusi kueri, tulis kueri grafik Anda sehingga traversal jalur dimulai dari node kardinalitas yang lebih rendah, terlepas dari arah traversal jalur. Pernyataan MATCH berikut menggunakan filter properti untuk mengurangi jumlah kemungkinan node awal, bukan menghitung semua kecocokan, lalu memfilter:

MATCH (p:Person {id: 10})-[own:Owns]->(a:Account)

Hal ini sangat penting untuk kueri jalur yang diukur:

MATCH (p:Person {id: 10})-[own:Owns]->{1,3}(a:Account)

Menggunakan penjelajahan jalur arah

Skema BigQuery Graph bersifat terarah, yang berarti setiap edge memiliki node sumber dan node tujuan. Meskipun sintaksis kueri grafik memungkinkan traversal jalur ke segala arah (misalnya, -[edge]-), sebaiknya gunakan traversal jalur terarah (misalnya, -[edge]-> atau <-[edge]-) untuk performa yang lebih baik. Setiap traversal jalur arah dapat menyebabkan penurunan performa.

Pernyataan MATCH berikut menggabungkan dua traversal arah dengan UNION ALL:

MATCH (a1:Account {id: 7})-[t:Transfers]->(a2:Account)
...
UNION ALL
...
MATCH (a1:Account  {id: 7})<-[t:Transfers]-(a2:Account)

Menggunakan sintaksis ANY atau ANY SHORTEST untuk pemeriksaan konektivitas

Kueri jalur yang dikuantifikasi dapat menampilkan jalur duplikat antara node sumber dan node tujuan. Jika sasaran Anda adalah memeriksa konektivitas dan Anda tidak memerlukan semua kemungkinan jalur, gunakan ANY atau ANY SHORTEST untuk mengurangi komputasi redundan dan meningkatkan efisiensi pencarian jalur. Misalnya, pernyataan MATCH berikut menggunakan ANY SHORTEST untuk mempertahankan hanya satu jalur di antara setiap pasangan node:

MATCH ANY SHORTEST (a1:Account)-[t:Transfers]->{1,3}(a2:Account)

Menentukan label secara eksplisit

Jika label node atau edge dihilangkan dalam kueri, BigQuery Graph akan menghitung semua label node dan edge yang memenuhi syarat. Enumerasi ini dapat menyebabkan lebih banyak label yang dipindai daripada yang diperlukan. Untuk menghindari hal ini, tentukan label untuk semua node dan edge dalam kueri Anda jika memungkinkan.

Misalnya, kueri berikut menentukan label Account dan Transfers:

GRAPH graph_db.FinGraph
MATCH (a1:Account)-[t:Transfers]->(a2:Account)
RETURN COUNT(*) AS num_transfers;

Hindari menghilangkan label, karena hal ini dapat memindai hubungan lain yang tidak diperlukan antara node. Dalam kueri berikut, a1 dapat mewakili akun atau orang, dan t dapat mewakili transfer atau kepemilikan akun.

GRAPH graph_db.FinGraph
MATCH (a1)-[t]->(a2)
RETURN COUNT(*) AS num_transfers;

Menggunakan satu pernyataan MATCH

BigQuery Graph memungkinkan Anda menyertakan beberapa pernyataan MATCH dalam satu kueri grafik. Pernyataan ini dihubungkan oleh variabel yang dideklarasikan beberapa kali yang mewakili node atau edge yang sama. Namun, penggunaan beberapa pernyataan MATCH dapat mengurangi manfaat kardinalitas di seluruh pernyataan. Untuk performa yang lebih baik, gunakan satu pernyataan MATCH.

Misalnya, kueri berikut setara, tetapi kueri pertama berperforma lebih baik karena menggunakan satu pernyataan MATCH:

-- Preferred syntax.
GRAPH graph_db.FinGraph
MATCH
  (p:Person {id: 1})-[o:Owns]->
  (a:Account)-[t:Transfers]->(a2:Account)
RETURN o.account_id, t.amount;
-- Avoid this syntax.
GRAPH graph_db.FinGraph
MATCH (p:Person {id: 1})-[o:Owns]->(a:Account)
MATCH (a:Account)-[t:Transfers]->(a2:Account)
RETURN o.account_id, t.amount;

Membatasi edge yang dilalui dari node berkardinalitas tinggi

Saat Anda membuat kueri grafik, beberapa node dapat memiliki jumlah edge masuk atau keluar yang jauh lebih besar dibandingkan dengan node lainnya. Node kardinalitas tinggi ini terkadang disebut node super atau node hub. Node super dapat menyebabkan masalah performa karena penjelajahan melaluinya mungkin melibatkan pemrosesan data dalam jumlah besar, yang menyebabkan kecondongan data dan waktu eksekusi yang lama.

Untuk mengoptimalkan kueri grafik dengan super node, gunakan fungsi ROW_NUMBER() dalam klausa FILTER atau klausa WHERE di MATCH untuk membatasi jumlah edge yang dilalui kueri dari atau ke node. Teknik ini sangat berguna jika Anda tidak memerlukan enumerasi lengkap dari semua koneksi dari atau ke super node.

Misalnya, jika beberapa akun di FinGraph memiliki jumlah transaksi yang besar, Anda dapat menggunakan ROW_NUMBER() untuk membatasi jumlah edge Transfers yang akan dipertimbangkan untuk setiap Account dan menghindari kueri yang tidak efisien:

GRAPH graph_db.FinGraph
MATCH (a1:Account)-[e1:Transfers WHERE e1 IN {
  GRAPH graph_db.FinGraph
  -- Sample 5 edges per source node
  MATCH -[selected_e:Transfers]->
    FILTER ROW_NUMBER() OVER (
      PARTITION BY SOURCE_NODE_ID(selected_e)) < 5
    RETURN selected_e
}]->{1,3}(a2:Account)
RETURN COUNT(*) AS cnt;

Mengambil sampel node atau edge perantara dalam kueri multi-hop

Anda dapat meningkatkan efisiensi kueri menggunakan ROW_NUMBER() untuk mengambil sampel node perantara dalam kueri multi-hop. Teknik ini membatasi jumlah jalur yang dipertimbangkan kueri untuk setiap node perantara. Untuk melakukannya, bagi kueri multi-hop menjadi beberapa pernyataan MATCH yang dipisahkan oleh NEXT, dan terapkan ROW_NUMBER() di titik tengah tempat Anda perlu mengambil sampel:

GRAPH graph_db.FinGraph
MATCH (a1:Account)-[e1:Transfers]->(a2:Account)
-- Sample 5 destination nodes per a1 source node
FILTER ROW_NUMBER() OVER (PARTITION BY ELEMENT_ID(a1)) < 5
RETURN a1, a2
NEXT
MATCH (a2)-[e2:Transfers]->(a3:Account)
RETURN a1.id AS src_id, a2.id AS mid_id, a3.id AS dst_id;

Langkah berikutnya