1. Ringkasan
Sebagian besar bug SQL yang lolos dari peninjauan kode adalah bug agregasi. Angka benar dalam tabel tempatnya berada, gabungan menyalinnya, dan totalnya salah tanpa diketahui.
BigQuery Graph memungkinkan Anda menjelaskan cara tabel terhubung satu kali, sebagai grafik properti, lalu mengkueri koneksi. Pengukuran grafik menambahkan satu hal lagi ke deskripsi tersebut: agregasi itu sendiri. Anda mendeklarasikan MEASURE(SUM(streams)) pada node yang memiliki angka, dan setiap kueri yang membaca grafik akan mendapatkan total yang tepat pada perincian yang tepat — tidak ada trik GROUP BY, tidak ada CTE yang harus diingat seseorang.
Dalam codelab ini, Anda akan membuat katalog musik lima tabel, menempatkan satu ukuran di dalamnya, dan melihat pertanyaan yang sama memberikan dua jawaban yang berbeda: 12,6 miliar dengan SUM, 5,1 miliar dengan AGG. Perbedaan ini adalah bentuk katalog — lagu yang ada di empat playlist akan menjadi empat baris setelah grafik diratakan, dan SUM menambahkan keempatnya. Kemudian, Anda mempelajari aturan yang membuat jawaban kedua benar.

Tempat Anda akan mengetik
Lab ini menggunakan tepat dua tempat, dalam urutan ini:
di mana | apa yang Anda lakukan di sana | |
1 | Terminal Cloud Shell | beberapa perintah, hanya pada langkah Penyiapan |
2 | Konsol BigQuery | semua hal lainnya: menempelkan kueri ke editor kueri, mengklik model grafik, melakukan chat dengan agen |
Setiap petunjuk diberi tag sehingga Anda selalu tahu petunjuk mana yang dimaksud:
- 👉💻 Cloud Shell — ketik ini di terminal Cloud Shell.
- 👉📋 Editor kueri — tempelkan ini ke editor kueri BigQuery, lalu klik Run.
- 👉🌐 Konsol — klik di konsol BigQuery. Tidak perlu mengetik apa pun kecuali jika langkahnya menyatakan demikian.
- 👀 — lihat hasilnya.
Yang akan Anda pelajari
- Cara mendeklarasikan ukuran pada tabel node — di pemodel grafik visual atau di SQL
- Cara
GRAPH_EXPANDmeratakan grafik menjadi satu tabel lebar - Mengapa
AGGadalah satu-satunya fungsi yang dapat membaca ukuran, dan apa yang dikatakan setiap upaya lainnya - Enam agregat yang didukung ukuran, dan cara melakukan aritmetika di seluruh agregat tersebut
- Cara satu ukuran menjawab pertanyaan yang dikelompokkan secara berbeda tanpa perubahan
- Opsional: cara GQL dan tab Grafik menjawab pertanyaan yang tidak dapat dijawab oleh total, dan cara agen data BigQuery menggunakan ukuran Anda tanpa diberi tahu tentangnya
Yang Anda butuhkan
- Akun Google dengan penagihan tersedia, dan browser. Anda tidak memerlukan project Google Cloud di awal — Penyiapan akan membuatnya untuk Anda.
- Khusus langkah chat opsional: API Analisis Data Gemini diaktifkan, dan peran Pembuat Agen Data Analisis Data Gemini.
Tidak ada yang perlu diinstal di komputer Anda. Semuanya berjalan di Cloud Shell dan konsol BigQuery.
Status dan biaya produk
BigQuery Graph tersedia secara umum. Pengukuran grafik, pemodel grafik visual, visualisasi grafik, dan penggunaan grafik sebagai sumber pengetahuan agen data berada dalam Pratinjau, yang tercakup dalam Persyaratan Penawaran Pra-GA.
GRAPH_EXPAND dan AGG berjalan dengan harga sesuai permintaan. Kueri GQL (langkah jalur opsional) memerlukan reservasi yang menggunakan edisi Enterprise atau Enterprise Plus, sesuai dengan dokumentasi — itulah sebabnya langkah tersebut bersifat opsional.
Set datanya berukuran beberapa kilobyte. Dengan harga sesuai permintaan, setiap kueri ditagih dengan minimum 10 MB, sehingga seluruh codelab dikenai biaya sebagian kecil sen.
2. Penyiapan
Ini adalah satu-satunya langkah yang menggunakan Cloud Shell. Langkah ini akan membuat project, mengaktifkan penagihan, dan membuat tabel mentah. Grafik, ukuran, dan setiap kueri dapat Anda jalankan setelahnya di konsol BigQuery.
Ada satu hal yang tidak dapat diberikan oleh lab ini: project Google Cloud dengan penagihan di dalamnya. Langkah 1 memberi Anda akun yang dapat membayar project tersebut; langkah 4 mengubah akun tersebut menjadi project. Lakukan dalam urutan tersebut — setiap langkah setelah 4 membaca project yang dibuat langkah 4.
1 · Dapatkan akun dengan penagihan (~1 menit)
👉🌐 Lakukan ini sebelum hal lainnya. Login dengan Akun Google yang penagihannya diaktifkan. Akun tersebut dapat digunakan. Jika akun Anda tidak memiliki akun penagihan, mulai uji coba gratis; uji coba ini akan memberi Anda akun penagihan, yang diperlukan untuk langkah 4.
2 · Buka Cloud Shell (~1 menit)
👉🌐 Konsol — klik Activate Cloud Shell di bagian atas konsol Google Cloud — ikon ini berbentuk terminal di header. Terminal akan terbuka di bagian bawah halaman.

👉🌐 Konsol — jika Anda diminta untuk memberikan otorisasi kapan saja hari ini, klik Beri otorisasi untuk melanjutkan.
👉💻 Cloud Shell — periksa akun yang digunakan untuk login ke Cloud Shell:
gcloud auth list
👀 Harapkan akun Anda sendiri ditandai dengan *, dan akun tersebut harus akun yang sama dengan yang Anda gunakan untuk login pada langkah 1. Jika tidak, jalankan gcloud auth login dan pilih yang tepat.
3 · Dapatkan lab (~1 menit)
👉💻 Cloud Shell — clone repo:
cd ~
rm -rf ~/bq-graph-measures-lab
git clone https://github.com/cuppibla/bq-graph-measures-lab.git
cd ~/bq-graph-measures-lab
4 · Buat project Anda (~2 menit)
👉💻 Cloud Shell — satu skrip menemukan akun penagihan Anda, membuat project di akun tersebut, dan mengarahkan Cloud Shell ke project tersebut:
cd ~/bq-graph-measures-lab
./setup_project.sh
👀 Harapkan ✓ untuk akun penagihan yang dipilih, ✓ untuk project yang dibuat, dan akhiran seperti:
Project ready: bq-graph-4271 Next: ./setup.sh
bq-graph-4271 adalah project ID Anda — ID Anda akan memiliki digit yang berbeda. Empat hal terjadi di sana:
penagihan | menggunakan akun | |
project | membuat | |
memilih | menulis ID ke | |
menunggu | polling hingga project baru benar-benar diizinkan untuk ditayangkan, hingga dua menit | |
🌐 Project yang sama kini ada di konsol — ID-nya ada di kartu Project info di Dasbor:

5 · Buat set data (~3 menit)
👉💻 Cloud Shell — satu skrip lagi yang membangun tabel:
cd ~/bq-graph-measures-lab
./setup.sh
Skrip mencetak setiap langkah saat dijalankan. Fungsinya, secara berurutan:
project | membaca project dari | |
API | mengaktifkan | |
dataset | membuat set data | |
check | menghitung baris di setiap tabel dan berhenti jika ada jumlah yang tidak sesuai | |
👀 Harapkan:
BigQuery Graph Measures · setup ✓ project: bq-graph-4271 ✓ BigQuery API enabled Creating dataset music (US) and five tables... ✓ music.Labels 2 rows ✓ music.Artists 3 rows ✓ music.Songs 5 rows ✓ music.Playlists 4 rows ✓ music.PlaylistEntries 10 rows 🎉 ready — open BigQuery Studio: https://console.cloud.google.com/bigquery?project=bq-graph-4271
Anda telah selesai menggunakan Cloud Shell. Anda dapat menutupnya.
6 · Buka BigQuery dan editor kueri
👉🌐 Konsol — klik link di akhir output, atau buka BigQuery dari menu navigasi. Di panel Explorer di sebelah kiri, luaskan project Anda: set data music dengan lima tabel.

👉🌐 Konsol — di bagian atas BigQuery Studio, di baris Create new, klik Kueri SQL. Tab editor kosong akan terbuka.

Biarkan tab ini. Setiap blok 👉📋 di lab ini akan ditempatkan di sini: pilih apa pun yang ada di editor, tempel blok baru di atasnya, klik Run. Hasilnya akan muncul di panel di bawahnya.
Mengenal tabel
Dua hal tentang tabel ini penting nanti. Setiap tabel mendeklarasikan kunci utamanya sebagai NOT ENFORCED: BigQuery tidak memeriksanya, tetapi grafik properti yang akan Anda buat memerlukan kunci eksplisit untuk mengetahui apa yang mengidentifikasi baris. Tabel terakhir, PlaylistEntries, adalah tabel penghubung: lagu yang ada di empat playlist memiliki empat baris di dalamnya. Di tabel itulah seluruh cerita terjadi.
Tabel-tabel tersebut saling terkait seperti ini: label mengontrak artis, artis merilis lagu, lagu ditempatkan di playlist melalui PlaylistEntries. Cymbal Records memiliki Ava Sterling dan Mina Okafor, dan melalui mereka empat lagu. Northwind Audio memiliki Kai Nakamura dan satu lagu, Midnight Drive.
meja | baris | kunci | apa yang dipegangnya |
Label | 2 |
| nama, anggaran pemasaran |
Artis | 3 |
| nama, yang merupakan label |
Lagu | 5 |
| judul, artis, streaming |
Playlist | 4 |
| nama, pengikut |
PlaylistEntries | 10 |
| lagu mana yang ada di playlist mana |
✅ Checkpoint: 🎉 ready di Cloud Shell, lima tabel di bagian music di Explorer, dan tab editor kueri kosong terbuka.
3. Membuat grafik — Opsi A: pemodel visual
Grafik properti adalah deskripsi tentang cara tabel terhubung. Anda dapat mengkliknya bersama-sama di pemodel grafik visual (langkah ini, semua klik) atau menuliskannya sebagai SQL (langkah berikutnya, satu tempel). Keduanya menghasilkan objek yang sama — lakukan salah satu, bukan keduanya.
1. Membuat shell grafik
👉🌐 Konsol — di BigQuery Studio, pada baris Buat baru, buka menu AI dan pengetahuan, lalu klik Grafik.
👉🌐 Console — masukkan MusicGraph sebagai Graph name dan music sebagai Graph destination in dataset. Wilayah diisi dari set data (Amerika Serikat).
👉🌐 Konsol — di bagian Sumber data, pilih lima tabel — Artis, Label, PlaylistEntries, Playlist, Lagu — lalu klik Buat.

👀 Kanvas terbuka dengan lima node berwarna dan tanpa garis di antaranya. Panel Detail di sebelah kanan mencantumkan Node (5) dan Edge (0). Setiap node sudah membawa kunci utama tabelnya dan semua kolomnya sebagai properti — klik node mana saja untuk melihatnya.

2. Menggambar empat tepi
Edge adalah kunci asing, yang digambar. Setiap panah mengarah dari tabel yang menyimpan kunci ke tabel yang ditujuknya.
👉🌐 Console — klik New edge. Dalam dialog Select table, pilih PlaylistEntries, lalu klik Add. Di panel Tambahkan tepi:
- Tetapkan Name ke
EntryToSong. - Klik Add primary key dan setujui
entry_id. - Di bagian Sumber, tetapkan Node sumber ke PlaylistEntries, lalu gunakan Tambahkan kolom yang dirujuk ke node dan Tambahkan kolom yang dirujuk di edge untuk memilih
entry_idbagi keduanya. - Di bagian Target, tetapkan Target node ke Lagu, lalu pilih
song_iduntuk Referenced columns in the node dan Referenced columns on the edge. - Klik Selesai.

👉🌐 Console — ulangi tiga kali lagi:
nama tepi | meja | node sumber → node target | kolom yang akan dipilih di kedua sisi |
| PlaylistEntries | PlaylistEntries → Playlists | sumber |
| Lagu | Lagu → Artis | sumber |
| Artis | Artis → Label | sumber |
Biarkan setiap tepi tanpa properti tambahan.
👀 Panel Detail kini menampilkan Edges (4), dan kanvas menampilkan rantai: Labels ← Artists ← Songs ← PlaylistEntries → Playlists.

3. Menambahkan ukuran
👉🌐 Konsol — klik node Songs, lalu ikon edit (pensil) di bagian atas panel Detail. Di bagian Properti label, klik Tambahkan properti, lalu Tambahkan kolom.
👉🌐 Konsol — masukkan total_streams sebagai Nama kolom, lalu ketik ini ke dalam kotak Ekspresi:
MEASURE(SUM(streams))
👉🌐 Konsol — klik Tambahkan, lalu Selesai.

4. Membaca kode yang ditulisnya, lalu memublikasikannya
👉🌐 Konsol — buka tab Kode di panel kanan. Modeler telah menulis pernyataan CREATE PROPERTY GRAPH untuk Anda. Scroll ke node Lagu: daftar propertinya kini diakhiri dengan
MEASURE(SUM(streams)) AS `total_streams`
Itulah seluruh fitur, dalam satu baris. Semua yang ada setelah langkah ini adalah tentang fungsi baris tersebut.

👉🌐 Konsol — klik Publikasikan.
✅ Checkpoint: di Explorer, music kini memiliki folder Graphs yang berisi MusicGraph. Klik: lima node, empat tepi, dan garis MEASURE(SUM(streams)) di tab Code. Lewati langkah berikutnya dan buka SUM dan AGG, berdampingan.
4. Membuat grafik — Opsi B: SQL
Lewati langkah ini jika Anda membuat grafik di pemodel.
👉📋 Editor kueri — tempel, lalu klik Run:
CREATE OR REPLACE PROPERTY GRAPH music.MusicGraph
NODE TABLES (
music.Labels KEY (label_id)
PROPERTIES (label_id, label_name, marketing_budget,
MEASURE(SUM(marketing_budget)) AS total_budget),
music.Artists KEY (artist_id)
PROPERTIES (artist_id, artist_name, label_id,
MEASURE(COUNT(artist_id)) AS artist_count),
music.Songs KEY (song_id)
PROPERTIES (song_id, title, artist_id, streams,
MEASURE(SUM(streams)) AS total_streams,
MEASURE(COUNT(song_id)) AS song_count),
music.Playlists KEY (playlist_id)
PROPERTIES (playlist_id, playlist_name, followers,
MEASURE(SUM(followers)) AS total_followers),
music.PlaylistEntries KEY (entry_id)
PROPERTIES (entry_id, playlist_id, song_id,
MEASURE(COUNT(entry_id)) AS placement_count)
)
EDGE TABLES (
music.PlaylistEntries AS EntryToSong
SOURCE KEY (entry_id) REFERENCES PlaylistEntries(entry_id)
DESTINATION KEY (song_id) REFERENCES Songs(song_id) NO PROPERTIES,
music.PlaylistEntries AS EntryToPlaylist
SOURCE KEY (entry_id) REFERENCES PlaylistEntries(entry_id)
DESTINATION KEY (playlist_id) REFERENCES Playlists(playlist_id) NO PROPERTIES,
music.Songs AS SongToArtist
SOURCE KEY (song_id) REFERENCES Songs(song_id)
DESTINATION KEY (artist_id) REFERENCES Artists(artist_id) NO PROPERTIES,
music.Artists AS ArtistToLabel
SOURCE KEY (artist_id) REFERENCES Artists(artist_id)
DESTINATION KEY (label_id) REFERENCES Labels(label_id) NO PROPERTIES
)
👀 Panel hasil menyatakan bahwa graf properti telah dibuat.

Baca sekali
Grafik memiliki lima tabel node dan empat tabel edge. Setiap tabel node memberi nama KEY dan mencantumkan PROPERTIES. Baris yang dimulai dengan MEASURE adalah bagian baru: setiap baris membungkus salah satu agregat yang didukung di sekitar properti dan memberikan alias, yang diperlukan.
Setiap tabel edge adalah kunci asing, yang dijelaskan sebagai berikut: SOURCE KEY pada tabel yang menyimpan kunci, DESTINATION KEY pada tabel yang ditujuknya. NO PROPERTIES berarti tepi tidak membawa apa pun dengan sendirinya.
Perhatikan bahwa PlaylistEntries muncul tiga kali: sekali sebagai tabel node, dan dua kali lagi sebagai tabel fisik di balik tepi EntryToSong dan EntryToPlaylist. Hal ini disengaja, dan nanti kami akan menjelaskan alasannya.
Lihat apa yang Anda buat
👉🌐 Console — di panel Explorer, luaskan music, lalu Graphs, dan klik MusicGraph. Halaman grafik terbuka di kanvas dengan lima node dan empat tepi. Klik node untuk melihat propertinya — ukuran dicantumkan dengan agregatnya. Buka tab Code untuk melihat pernyataan di balik gambar.

✅ Checkpoint: music memiliki folder Graphs yang berisi MusicGraph, dan tab Code menampilkan MEASURE(SUM(streams)) AS total_streams.
5. SUM dan AGG, berdampingan
Ini adalah seluruh codelab dalam satu kueri. Kedua kolom mencoba menjawab pertanyaan yang sama — total streaming per label — dari tabel yang sama.
Tabel tersebut adalah tabel yang dihasilkan GRAPH_EXPAND. Proses ini meratakan grafik: dimulai dari satu tabel dan mengikuti setiap tepi ke luar sebagai LEFT JOIN, hingga setiap tabel yang terhubung berada berdampingan dalam satu hasil lebar. Satu baris per penempatan, bukan satu per lagu, dan setiap kolom diberi nama TableLabel_property. Lihat sebelum Anda membuat kueri.
👉📋 Editor kueri — tempel, lalu klik Run:
SELECT Labels_label_name, Songs_title, Songs_streams, Playlists_playlist_name
FROM GRAPH_EXPAND("music.MusicGraph")
ORDER BY Songs_title, Playlists_playlist_name
👀 Harapkan 10 baris — satu untuk setiap penempatan di PlaylistEntries, yang persis seperti yang dimuat oleh Penyiapan. Neon Summer menempati empat di antaranya, satu per playlist yang ada di dalamnya, dan Songs_streams dibaca 2.000.000.000 di setiap playlist. Tidak ada yang salah dengan baris tersebut; playlistnya memang empat. Namun, kolom yang termasuk dalam lagu kini diulang di seluruh baris yang termasuk dalam penempatan, dan itulah seluruh masalah yang diukur oleh kueri berikutnya.
Sekarang perbandingannya.
👉📋 Editor kueri — tempel, lalu klik Run:
SELECT
Labels_label_name,
SUM(Songs_streams) AS with_sum,
AGG(Songs_total_streams) AS with_agg
FROM GRAPH_EXPAND("music.MusicGraph")
GROUP BY 1 ORDER BY 1
👀 Hasil:
Labels_label_name | with_sum | with_agg |
Cymbal Records | 12.600.000.000 | 5.100.000.000 |
Northwind Audio | 9.000.000.000 | 4.500.000.000 |

Periksa secara manual. Empat lagu Cymbal di-streaming sebanyak 2,0 miliar, 1,5 miliar, 1,2 miliar, dan 0,4 miliar kali. Jumlahnya adalah 5,1 miliar. AGG benar. SUM dua setengah kali lebih besar, dan satu lagu Northwind berlipat ganda.
Tiga sintaksis baru
GRAPH_EXPAND("music.MusicGraph")adalah fungsi bernilai tabel yang mengubah grafik menjadi satu tabel lebar, dengan mengikuti setiap edge sebagaiLEFT JOIN. Setiap kolom diberi namaTableLabel_property, sehinggaSongs_streamsadalah kolom mentah dari tabel Lagu danSongs_total_streamsadalah ukuran yang Anda deklarasikan.SUM(Songs_streams)adalah SQL biasa di tabel lebar tersebut — dan mewarisi setiap duplikat yang dihasilkan perataan.AGG(Songs_total_streams)mengevaluasi ukuran sesuai dengan cara deklarasinya:SUM(streams)sekali persong_id, berapa pun jumlah baris yang ditempati lagu dalam tabel lebar.
✅ Checkpoint: dua label, dua kolom, dan angka with_agg cocok dengan jumlah hitungan manual.
6. Alasan SUM menghitung terlalu banyak
Ambil satu lagu dan lihat apa yang dilakukan penggabungan tersebut.
👉📋 Editor kueri — tempel, lalu klik Run:
SELECT 'BEFORE - the Songs table' AS step, title, streams, CAST(NULL AS STRING) AS playlist
FROM music.Songs WHERE title = 'Neon Summer'
UNION ALL
SELECT 'AFTER - joined to playlists', s.title, s.streams, pl.playlist_name
FROM music.Songs s
LEFT JOIN music.PlaylistEntries e ON e.song_id = s.song_id
LEFT JOIN music.Playlists pl ON pl.playlist_id = e.playlist_id
WHERE s.title = 'Neon Summer'
ORDER BY step DESC, playlist
👀 Hasil:
langkah | judul | streaming | playlist |
SEBELUM - tabel Lagu | Neon Summer | 2.000.000.000 | null |
SETELAH - bergabung ke playlist | Neon Summer | 2.000.000.000 | Gym Pump |
SETELAH - bergabung ke playlist | Neon Summer | 2.000.000.000 | Sedang Populer |
SETELAH - bergabung ke playlist | Neon Summer | 2.000.000.000 | Rising Pop |
SETELAH - bergabung ke playlist | Neon Summer | 2.000.000.000 | Perjalanan Darat |

Satu baris menjadi empat. Jumlah streaming tidak berubah — jumlah tersebut disalin. Jumlahkan apa yang dilakukan salinan ke Cymbal Records: Neon Summer 2,0 miliar di empat playlist adalah 8,0, Paper Crown 1,5 miliar di dua playlist adalah 3,0, Double Shot 1,2 di satu playlist, Slow Arrow 0,4 di satu playlist. Jumlahnya adalah 12,6 miliar, yaitu angka SUM yang ditampilkan. Northwind's Midnight Drive ada di dua playlist, sehingga 4,5 miliar menjadi 9,0.
Ini adalah fan-out, dan bukan bug dalam gabungan. Baris playlist itu nyata. Kesalahannya adalah menjumlahkan angka yang termasuk dalam lagu di seluruh baris yang termasuk dalam penempatan.
Ukuran ini memperbaikinya karena dideklarasikan di node Lagu bersama dengan KEY (song_id). Kuncinya adalah tekstur. Saat AGG mengevaluasi total_streams, akan menggabungkan sekali per kunci lagu, lalu di-roll up ke apa pun yang Anda kelompokkan.
Apa yang berubah
Anda dulu menulis | Dengan ukuran |
|
|
|
|
Tiga |
|
CTE yang menggabungkan sebelum bergabung | Tidak ada. |
✅ Checkpoint: lima baris — satu SEBELUM, empat SETELAH — dan Anda dapat membangun kembali 12,6 miliar dari baris tersebut.
7. Aturannya: hanya AGG yang membaca ukuran
Ukuran memiliki jenisnya sendiri, MEASURE, dan tepat satu fungsi yang menerimanya. Empat kueri di bawah sengaja gagal — jalankan setiap kueri dan baca error merah. Berikut adalah empat cara yang dicoba semua orang terlebih dahulu, dan mengetahui apa yang mereka katakan akan menghemat waktu di kemudian hari.
👉📋 Editor kueri — AGG pada kolom biasa:
SELECT AGG(Songs_streams) FROM GRAPH_EXPAND("music.MusicGraph")
👀 No matching signature for aggregate function AGG ... Argument 1: expected MEASURE

👉📋 Editor kueri — kolom ukuran tanpa AGG:
SELECT Songs_total_streams FROM GRAPH_EXPAND("music.MusicGraph") LIMIT 1
👀 Returning expressions of type MEASURE is not allowed

👉📋 Editor kueri — ukuran yang dirujuk dalam GQL, yang tidak pernah melihat ukuran sama sekali (yang ini adalah kueri GQL — lihat catatan edisi dalam ringkasan):
GRAPH music.MusicGraph
MATCH (s:Songs)
RETURN s.total_streams
LIMIT 1
👀 total_streams is not exposed by element type GRAPH_NODE(...)

👉📋 Editor kueri — SUM kolom pengukuran, yang paling menarik:
SELECT Labels_label_name, SUM(Songs_total_streams)
FROM GRAPH_EXPAND("music.MusicGraph")
GROUP BY 1
👀 MEASURE-typed arguments are only permitted in the AGG function

Jadi, sistem pengetikan akan menerapkan aturan untuk Anda. Pengukuran hanya dapat dilihat melalui GRAPH_EXPAND, dan hanya dapat dibaca melalui AGG. 12,6 miliar yang dihitung berlebihan dari sebelumnya hanya dapat berasal dari menjumlahkan kolom mentah, bukan dari kesalahan penanganan pengukuran.
✅ Checkpoint: empat error merah, dan Anda dapat mengatakan aturan mana yang diterapkan oleh setiap error.
8. Setiap agregasi yang didukung metrik
MEASURE() mencakup salah satu dari enam agregat: SUM, AVG, MIN, MAX, COUNT, dan COUNT(DISTINCT). Buat ulang grafik dengan keenamnya di node Lagu. Edge tetap NO PROPERTIES, yang merupakan praktik terbaik yang didokumentasikan saat edge berbagi tabel fisiknya dengan node.
👉📋 Editor kueri — tempel, lalu klik Run:
CREATE OR REPLACE PROPERTY GRAPH music.MusicGraph
NODE TABLES (
music.Labels KEY (label_id)
PROPERTIES (label_id, label_name, marketing_budget,
MEASURE(SUM(marketing_budget)) AS total_budget),
music.Artists KEY (artist_id)
PROPERTIES (artist_id, artist_name, label_id,
MEASURE(COUNT(artist_id)) AS artist_count),
music.Songs KEY (song_id)
PROPERTIES (song_id, title, artist_id, streams,
MEASURE(SUM(streams)) AS total_streams,
MEASURE(AVG(streams)) AS avg_streams,
MEASURE(MIN(streams)) AS min_streams,
MEASURE(MAX(streams)) AS max_streams,
MEASURE(COUNT(song_id)) AS song_count,
MEASURE(COUNT(DISTINCT artist_id)) AS distinct_artists),
music.Playlists KEY (playlist_id)
PROPERTIES (playlist_id, playlist_name, followers,
MEASURE(SUM(followers)) AS total_followers),
music.PlaylistEntries KEY (entry_id)
PROPERTIES (entry_id, playlist_id, song_id,
MEASURE(COUNT(entry_id)) AS placement_count)
)
EDGE TABLES (
music.PlaylistEntries AS EntryToSong
SOURCE KEY (entry_id) REFERENCES PlaylistEntries(entry_id)
DESTINATION KEY (song_id) REFERENCES Songs(song_id) NO PROPERTIES,
music.PlaylistEntries AS EntryToPlaylist
SOURCE KEY (entry_id) REFERENCES PlaylistEntries(entry_id)
DESTINATION KEY (playlist_id) REFERENCES Playlists(playlist_id) NO PROPERTIES,
music.Songs AS SongToArtist
SOURCE KEY (song_id) REFERENCES Songs(song_id)
DESTINATION KEY (artist_id) REFERENCES Artists(artist_id) NO PROPERTIES,
music.Artists AS ArtistToLabel
SOURCE KEY (artist_id) REFERENCES Artists(artist_id)
DESTINATION KEY (label_id) REFERENCES Labels(label_id) NO PROPERTIES
)

Sekarang, baca kembali semuanya. Setiap ukuran melewati AGG, dan kolom terakhir menunjukkan bahwa hasil AGG adalah nilai biasa yang dapat Anda gunakan untuk melakukan perhitungan aritmatika. Grafik baru saja berubah, jadi hapus centang Gunakan hasil yang di-cache terlebih dahulu (Lainnya → Setelan kueri).
👉📋 Editor kueri — tempel, lalu klik Run:
SELECT
Labels_label_name,
AGG(Songs_total_streams) AS total_streams,
AGG(Songs_avg_streams) AS avg_streams,
AGG(Songs_min_streams) AS min_streams,
AGG(Songs_max_streams) AS max_streams,
AGG(Songs_song_count) AS songs,
AGG(Songs_distinct_artists) AS artists,
AGG(Songs_total_streams) / AGG(Songs_song_count) AS streams_per_song
FROM GRAPH_EXPAND("music.MusicGraph")
GROUP BY 1
ORDER BY 1
👀 Hasil:
Labels_label_name | total_streams | avg_streams | min_streams | max_streams | lagu | artists | streams_per_song |
Cymbal Records | 5.100.000.000 | 1.275.000.000 | 400.000.000 | 2.000.000.000 | 4 | 2 | 1.275.000.000 |
Northwind Audio | 4.500.000.000 | 4.500.000.000 | 4.500.000.000 | 4.500.000.000 | 1 | 1 | 4.500.000.000 |

Setiap angka dihitung dari empat lagu untuk Cymbal dan satu lagu untuk Northwind, bukan dari sepuluh baris penempatan. Khususnya AVG, akan salah jika dihitung dengan cara lain: merata-ratakan kolom mentah di seluruh baris penempatan akan menghasilkan 1,575 miliar untuk Cymbal, karena 2 miliar Neon Summer dihitung empat kali.
Jadi, "tukar SUM dengan AGG" sebenarnya adalah dua keputusan. Saat mendeklarasikan ukuran, Anda tetap memilih mana dari enam agregat tersebut. Saat Anda membacanya, fungsinya selalu AGG.
✅ Checkpoint: satu baris per label, masing-masing tujuh angka, dan streams_per_song sama dengan avg_streams.
9. Ubah pengelompokan, bukan ukuran
Ukuran yang sama menjawab pertanyaan yang berbeda. Mengelompokkan menurut playlist, bukan label.
👉📋 Editor kueri — tempel, lalu klik Run:
SELECT
Playlists_playlist_name,
AGG(Songs_total_streams) AS streams,
AGG(Songs_song_count) AS songs
FROM GRAPH_EXPAND("music.MusicGraph")
GROUP BY 1
ORDER BY 2 DESC
👀 Hasil:
Playlists_playlist_name | streaming | lagu |
Perjalanan Darat | 6.900.000.000 | 3 |
Gym Pump | 6.500.000.000 | 2 |
Sedang Populer | 4.700.000.000 | 3 |
Rising Pop | 3.500.000.000 | 2 |

Dua baris AGG sama persis dengan baris dari SUM dan AGG, berdampingan. Hanya GROUP BY yang dipindahkan. Road Trip berisi Neon Summer, Midnight Drive, dan Slow Arrow, dan setiap lagu dihitung satu kali dalam playlist tersebut — yang persis seperti yang dimaksud dengan "streaming yang mencapai playlist ini".
Orang yang menulis ukuran memutuskan butirannya sekali. Setiap kueri berikutnya, oleh siapa pun, akan mewarisinya.
✅ Checkpoint: Road Trip di posisi teratas dengan 6,9 miliar.
10. Melihat hasil yang diberikan GRAPH_EXPAND
Anda tidak perlu menjalankan GRAPH_EXPAND untuk mempelajari bentuknya. Prosedur sistem BQ.SHOW_GRAPH_EXPAND_SCHEMA menulis daftar kolom ke dalam variabel.
👉📋 editor kueri — tempel ketiga baris, lalu klik Run:
DECLARE schema STRING DEFAULT '';
CALL BQ.SHOW_GRAPH_EXPAND_SCHEMA('music.MusicGraph', schema);
SELECT schema;
👀 Hasilnya adalah satu string JSON. Setiap kolom memiliki nama, jenis, dan mode, dan setiap kolom ukuran membawa "is_measure": true. Untuk grafik yang baru saja Anda buat, Anda akan mendapatkan hal berikut, antara lain:
nama | jenis | is_measure | |
Songs_title | STRING | ||
Songs_streams | BILANGAN BULAT | ||
Songs_total_streams | BILANGAN BULAT | true | |
Songs_avg_streams | FLOAT | true | |
Songs_distinct_artists | BILANGAN BULAT | true | |
PlaylistEntries_placement_count | BILANGAN BULAT | true | |

Deskripsi atau sinonim yang Anda tetapkan di properti juga akan muncul di sini. Langkah chat opsional menunjukkan siapa yang membaca pesan tersebut.
✅ Checkpoint: string JSON dengan is_measure di setiap kolom yang Anda deklarasikan dengan MEASURE.
11. Yang dibutuhkan GRAPH_EXPAND dari bentuk grafik
Tidak ada yang perlu dijalankan pada langkah ini — cukup baca. GRAPH_EXPAND membangun tabel lebarnya dengan rangkaian LEFT JOIN, dimulai dari satu tabel dan mengikuti tepi ke luar. Tiga aturan berikut berasal dari hal tersebut, dan MusicGraph memenuhi semuanya.

Tepat satu tabel node root. Root adalah tabel node yang kuncinya tidak muncul di tabel lain — tabel yang tidak memiliki titik ujung. Di MusicGraph, PlaylistEntries adalah: sumber dari dua edge dan tujuan dari tidak ada edge. Tabel lebar memiliki 10 baris, satu per penempatan.
Setiap tepi adalah banyak-ke-satu, sumber ke tujuan. Setiap entri memiliki satu lagu dan satu playlist, setiap lagu memiliki satu artis, setiap artis memiliki satu label. Itulah sebabnya tabel lebar tidak pernah melebar di luar baris root. Data yang tidak dapat dijangkau oleh root tidak muncul: lagu tanpa penempatan tidak akan ada dalam tabel lebar.
Hubungan many-to-many menjadi node. Lagu dan playlist memiliki hubungan many-to-many. Jika Anda mendeklarasikan tabel penghubung sebagai satu tepi dari Lagu ke Daftar Putar, GRAPH_EXPAND akan mengabaikannya karena ambigu — dan tanpa tepi yang dapat digunakan, akan gagal. Mempromosikan PlaylistEntries ke tabel node dengan dua edge many-to-one di luarnya adalah pola yang didokumentasikan, dan itulah yang Anda lakukan saat membangun grafik.
12. (OPSIONAL) Jalur dengan GQL
Setiap pertanyaan sejauh ini memiliki angka sebagai jawaban. Yang ini tidak. Ke mana streaming Cymbal menjangkau pendengar? adalah pertanyaan tentang rute melalui grafik, dan total tidak dapat menjawabnya — pada saat Anda menjumlahkan, rute tersebut sudah tidak ada.
1. Tanyakan di mana aliran tersebut mendarat
👉📋 Editor kueri — tempel, lalu klik Run:
GRAPH music.MusicGraph
MATCH (l:Labels)<-[:ArtistToLabel]-(a:Artists)<-[:SongToArtist]-(s:Songs)
<-[:EntryToSong]-(e:PlaylistEntries)-[:EntryToPlaylist]->(pl:Playlists)
WHERE l.label_name = 'Cymbal Records'
RETURN pl.playlist_name, pl.followers,
SUM(s.streams) AS streams_reaching_this_playlist,
STRING_AGG(s.title, ', ') AS songs
GROUP BY pl.playlist_name, pl.followers
ORDER BY streams_reaching_this_playlist DESC
👀 Nantikan empat playlist:
pl.playlist_name | pl.followers | streams_reaching_this_playlist | lagu |
Sedang Populer | 35.000.000 | 4.700.000.000 | Double Shot, Neon Summer, Paper Crown |
Rising Pop | 2.000.000 | 3.500.000.000 | Neon Summer, Paper Crown |
Perjalanan Darat | 5.000.000 | 2.400.000.000 | Neon Summer, Slow Arrow |
Gym Pump | 3.000.000 | 2.000.000.000 | Neon Summer |

Baca baris MATCH sebagai kalimat: mulai dari label, kembali ke artisnya, kembali ke lagunya, kembali ke entri playlist tempat lagu tersebut berada, lalu maju ke playlist. Panah menunjukkan cara tepi dideklarasikan; <- berjalan mundur.
Sekarang, jumlahkan kolom ketiga tersebut. 12,6 miliar — angka yang diberikan SUM kepada Anda di langkah keempat, yang salah.
Ini dia yang benar. Saat itu, pertanyaannya adalah berapa banyak streaming Cymbal, dan sebuah lagu dihitung satu kali, berapa pun jumlah playlist yang memuatnya. Pertanyaan ini adalah tempat aliran tersebut menjangkau, dan lagu di empat playlist benar-benar menjangkau empat audiens. Duplikasi GRAPH_EXPAND menghasilkan error untuk satu pertanyaan dan jawaban untuk pertanyaan lainnya. AGG tidak pernah membahas duplikat yang buruk, tetapi tentang mencocokkan aritmatika dengan pertanyaan.
2. Menampilkan jalur itu sendiri
Hapus agregasi dan minta rute.
👉📋 Editor kueri — tempel, lalu klik Run:
GRAPH music.MusicGraph
MATCH p = (l:Labels)<-[:ArtistToLabel]-(a:Artists)<-[:SongToArtist]-(s:Songs)
<-[:EntryToSong]-(e:PlaylistEntries)-[:EntryToPlaylist]->(pl:Playlists)
WHERE l.label_name = 'Cymbal Records'
RETURN TO_JSON(p) AS path
p = memberi nama seluruh kecocokan, dan TO_JSON merendernya.
👀 Harapkan 8 baris, satu kolom path. Setiap sel adalah array JSON dari node dan tepi di sepanjang satu rute, setiap node membawa labels dan properties-nya.

Delapan baris untuk empat lagu, karena ada rute per penempatan, bukan per lagu.
3. Membuka tab Grafik
👉🌐 Konsol — di atas hasil, klik Grafik.
Tab ini hanya muncul jika hasil berisi elemen grafik. Kueri sebelumnya menampilkan angka, sehingga tidak memiliki tab Grafik; kueri ini menampilkan jalur, sehingga memilikinya.

Anda akan mendapatkan sudut grafik Cymbal yang digambar sebagai tata letak gaya, dengan jumlah node dan tepi yang terlihat serta chip per label. Tarik node untuk memisahkan tata letak; klik salah satu node untuk membaca propertinya.
✅ Checkpoint: kolom ketiga kueri pertama berjumlah 12,6 miliar, kueri kedua menampilkan 8 jalur, dan tab Grafik menggambarkannya.
13. (OPSIONAL) Berinteraksi dengan grafik
Tidak ada SQL dalam langkah ini. Agen data BigQuery dapat menggunakan grafik sebagai sumber pengetahuan mereka, dan dokumentasi mengatakan bahwa mereka menggunakan ukuran untuk agregasi multi-level. Mari kita lihat apakah itu benar.
1. Membuat agen
👉🌐 Konsol — di menu navigasi BigQuery di sebelah kiri, klik Agen, lalu Katalog agen, lalu Buat agen.
👉🌐 Console — ketik Music graph agent di Agent name, dan ini di Agent description:
Ask questions about labels, artists, songs and playlists in the music property graph.
👉🌐 Konsol — di bagian Sumber pengetahuan, klik Tambahkan sumber. Dalam dialog Select sources, luaskan project Anda, luaskan music, luaskan Graphs, centang MusicGraph, lalu klik Confirm.
👀 Tombol Tambahkan sumber berwarna abu-abu. Agen dapat menyimpan paling banyak satu grafik, dan tidak dapat menggabungkan grafik dengan tabel.

👉🌐 Konsol — biarkan Wilayah seperti yang ditetapkan dari lokasi grafik. Klik Simpan, lalu Publikasikan. Di panel Publishing channels, klik Publish agent dan tutup konfirmasi.
2. Ajukan pertanyaan
👉🌐 Konsol — klik Buat percakapan. Halaman chat akan terbuka. Ketik ini di kotak Ajukan pertanyaan di bagian bawah, lalu tekan Enter:
For each label, show total streams and how many playlists their songs are on
👀 Agen menampilkan tabel dan ringkasan satu kalimat:
label_name | total_streams | playlist_placements |
Cymbal Records | 5.100.000.000 | 8 |
Northwind Audio | 4.500.000.000 | 2 |

5,1 miliar. Tidak ada yang memberi tahu agen tentang fan-out, dan agen tidak termasuk di dalamnya.
3. Membaca kueri yang ditulisnya
👉🌐 Konsol — di menu navigasi, klik Jobs explorer, lalu klik tugas terbaru. Labelnya mencakup ca-bq-job: true dan data-agent-id dengan ID agen Anda, dan kuerinya adalah:
SELECT
Labels_label_name AS label_name,
AGG(Songs_total_streams) AS total_streams,
AGG(PlaylistEntries_placement_count) AS playlist_placements
FROM GRAPH_EXPAND("music.MusicGraph")
GROUP BY label_name
ORDER BY total_streams DESC

Fitur ini menggunakan GRAPH_EXPAND dan AGG dengan sendirinya, karena ukuran ada dalam skema yang dibacanya. Tidak ada yang menyebutkan mereka dalam deskripsi agen.
✅ Checkpoint: 5,1 miliar dalam jawaban chat, dan AGG(...) dalam SQL tugas.
14. Pembersihan
👉💻 Cloud Shell — hapus set data, tabelnya, dan grafik properti:
cd ~/bq-graph-measures-lab
./cleanup.sh
👀 Harapkan ✓ dropped YOUR_PROJECT_ID.music (tables and graph).
Jika Anda membuat agen data opsional, hapus agen tersebut di konsol pada bagian Agents → Agent catalog. Jika ./setup_project.sh Anda membuat project hanya untuk lab ini, cara paling rapi untuk membersihkannya adalah dengan menonaktifkan seluruh project — ID-nya ada di ~/project_id.txt.
15. Selamat
Anda mendeklarasikan satu baris, MEASURE(SUM(streams)), dan baris tersebut mengubah 12,6 miliar menjadi 5,1 miliar — untuk Anda, dan untuk setiap kueri yang ditulis siapa pun terhadap grafik tersebut setelahnya, termasuk kueri yang ditulis agen.
Yang telah Anda pelajari
- Ukuran adalah agregat yang dideklarasikan pada node, di samping
KEYyang menetapkan perinciannya. GRAPH_EXPANDmeratakan grafik menjadi satu tabel lebar denganTableLabel_propertykolom.AGGadalah satu-satunya fungsi yang membaca ukuran, dan sistem jenis menerapkannya dengan empat cara berbeda.- Enam agregat tersedia, dan hasil
AGGadalah nilai biasa yang dapat Anda bagi. - Mengubah
GROUP BYakan menanyakan kembali pertanyaan tanpa menyentuh ukuran. GRAPH_EXPANDmenginginkan satu root, edge many-to-one, dan persimpangan yang dipromosikan ke node.
Tabel keputusan
Gejala | Penyebab | Perbaiki |
Total yang terlalu besar |
| deklarasikan ukuran, baca dengan |
"expected MEASURE, found INT64" (diharapkan MEASURE, ditemukan INT64) |
| menggunakan |
"Ekspresi jenis UKURAN tidak diizinkan" | mengukur kolom tanpa | bungkus: |
"tidak diekspos oleh jenis elemen" | ukuran yang dirujuk dalam GQL | hanya mengukur live di belakang |
| persimpangan yang dimodelkan sebagai tepi | mempromosikan tabel persimpangan ke node |
Nomor lama setelah mengubah grafik | hasil yang di-cache | hapus centang Gunakan hasil yang di-cache |
Yang tidak kami bahas (dengan sengaja)
Deskripsi dan sinonim pada properti · kueri dan glosarium terverifikasi untuk agen data · GQL di luar satu MATCH · ukuran di lebih dari satu grafik. Setiap lab memiliki labnya sendiri.
Pelajari lebih lanjut
- Bekerja dengan ukuran
- Membuat dan membuat kueri grafik properti
- Ringkasan analisis percakapan
- Repositori lab — setiap kueri dalam codelab ini, diberi nomor berdasarkan langkah