開始使用 BigQuery Graph Measures

1. 總覽

通過程式碼審查的 SQL 錯誤大多是彙整錯誤。表格中的數字正確無誤,但聯結會複製該數字,導致總數有誤。

BigQuery Graph 可讓您以屬性圖譜的形式,描述資料表之間的連結,然後查詢這些連結。圖表指標會在說明中加入另一個項目:匯總本身。您可以在擁有該數字的節點上宣告 MEASURE(SUM(streams)),而讀取圖表的每個查詢都會在正確的粒度取得正確的總計,不需要 GROUP BY 技巧,也不需要有人記得 CTE。

在本程式碼研究室中,您將建構五個資料表的音樂目錄,並在目錄中加入一個指標,然後觀察同一個問題傳回的兩個不同答案:126 億 (使用 SUM) 和 51 億 (使用 AGG)。這個間隙就是目錄的形狀,如果歌曲出現在四個播放清單中,圖表就會有四列,而 SUM 會新增所有四列。然後瞭解第二個句子正確的原因。

將一個「歌曲」列複製到四個刊登位置列:SUM 會新增副本,AGG 會根據 song_id 收合副本

輸入內容的位置

本實驗室會使用兩個地點,順序如下:

媒介

你在那裡做什麼

1

Cloud Shell 終端機

少數指令,僅限「設定」步驟

2

BigQuery 控制台

其他所有操作:將查詢貼到查詢編輯器、點按圖表建模工具、與代理交談

每項指令都會加上標記,方便你辨識指令的意義:

  • 👉💻 Cloud Shell:在 Cloud Shell 終端機中輸入這個指令。
  • 👉📋 查詢編輯器:將這段程式碼貼到 BigQuery 查詢編輯器,然後按一下「執行」。
  • 👉🌐 控制台 - 在 BigQuery 控制台中隨意點選,除非步驟中另有說明,否則不需要輸入任何內容。
  • 👀 - 查看結果。

課程內容

  • 如何在節點資料表上宣告指標 - 在視覺化圖表模型工具或 SQL 中
  • GRAPH_EXPAND 如何將圖譜攤平為一個寬資料表
  • 為什麼 AGG 是唯一可以讀取指標的函式,以及其他嘗試會傳回的內容
  • 指標支援的六個匯總,以及如何對這些匯總執行算術運算
  • 某項指標如何回答分組方式不同的問題,且沒有任何變更
  • 選用:瞭解 GQL 和「圖表」分頁如何回答總計無法回答的問題,以及 BigQuery 資料代理程式如何使用您的指標,而不需事先得知這些指標

軟硬體需求

  • 具備可啟用帳單的 Google 帳戶和瀏覽器。您不需要預先建立 Google Cloud 專案,設定程序會為您建立專案。
  • 僅限選用的對話步驟:啟用 Gemini Data Analytics API,並具備 Gemini Data Analytics 資料代理建立者角色。

你不需要在電腦上安裝任何軟體。所有作業都會在 Cloud Shell 和 BigQuery 控制台中執行。

產品狀態和費用

BigQuery Graph 現已正式發布。圖表指標、視覺化圖表模型工具、圖表視覺化,以及將圖表做為資料代理程式知識來源的功能,目前處於預先發布版,並受到《正式發布前產品條款》規範。

GRAPH_EXPAND 和 AGG 均採用以量計價模式。根據文件,GQL 查詢 (選用路徑步驟) 需要使用 Enterprise 或 Enterprise Plus 版本的預留項目,因此這個步驟是選用步驟。

資料集大小為幾 KB。以量計價的最低費用為 10 MB,因此整個程式碼研究室的費用不到一美分。

2. 設定

這是唯一需要使用 Cloud Shell 的步驟。這個指令會建立專案、啟用帳單功能,並建構原始資料表。之後您可以在 BigQuery 控制台中執行圖表、指標和所有查詢。

本實驗室無法提供已啟用計費功能的 Google Cloud 專案。步驟 1 會提供可支付費用的帳戶,步驟 4 則會將該帳戶轉換為專案。請按照這個順序操作,因為步驟 4 之後的每個步驟都會讀取步驟 4 建立的專案。

1. 取得含帳單的帳戶 (約 1 分鐘)

👉🌐 請務必先完成這項操作。使用已啟用帳單功能的 Google 帳戶登入。任何這類帳戶都可以。如果沒有,請開始免費試用,這樣您就會有帳單帳戶,這也是步驟 4 的必要條件。

2 · 開啟 Cloud Shell (約 1 分鐘)

👉🌐 控制台:點選 Google Cloud 控制台頂端的「啟用 Cloud Shell」,即標題中的終端機形狀圖示。頁面底部會開啟終端機。

從 Google Cloud 控制台標題列啟用 Cloud Shell

👉🌐 控制台:如果系統在今天任何時間提示您授權,請點選「授權」繼續操作。

👉💻 Cloud Shell - 檢查 Cloud Shell 登入的帳戶:

gcloud auth list

👀 預期自己的帳戶會標示 *,且必須與步驟 1 中登入的帳戶相同。如果不是,請執行 gcloud auth login 並選擇正確的項目。

3. 取得實驗室 (約 1 分鐘)

👉💻 Cloud Shell - 複製存放區:

cd ~
rm -rf ~/bq-graph-measures-lab
git clone https://github.com/cuppibla/bq-graph-measures-lab.git
cd ~/bq-graph-measures-lab

4 · 建立專案 (約 2 分鐘)

👉💻 Cloud Shell:一個指令碼會找出您的帳單帳戶、在該帳戶中建立專案,並將 Cloud Shell 指向該專案:

cd ~/bq-graph-measures-lab
./setup_project.sh

👀 系統會為所選帳單帳戶和建立的專案各產生一個 ✓✓,並在結尾加上:

Project ready: bq-graph-4271
  Next:  ./setup.sh

bq-graph-4271 是您的專案 ID,您的專案 ID 會有不同的數字。當中會發生四件事:

帳單

如果有的話,會採用最新的 [YYYY-MM-DD] GDP Credit: 帳戶,否則會採用任何其他已開啟的帳單帳戶

project

建立 bq-graph-XXXX,並將該帳單帳戶連結至

選取

將 ID 寫入 ~/project_id.txt 並執行 gcloud config set project,因此之後不需要輸入 ID

等待

輪詢,直到新專案實際獲准放送為止,最多兩分鐘

🌐 控制台中現在有相同的專案,其 ID 位於資訊主頁的「專案資訊」資訊卡中:

控制台資訊主頁上的專案 ID

5 · 建立資料集 (~3 分鐘)

👉💻 Cloud Shell - 另一個指令碼會建構表格:

cd ~/bq-graph-measures-lab
./setup.sh

指令碼執行時會列印每個步驟。這段程式碼會依序執行下列作業:

project

從 gcloud config 讀取專案,如果沒有專案,則拒絕繼續

API

啟用 bigquery.googleapis.com

資料集

在美國多區域建立 music 資料集和五個資料表,每個資料表都包含 PRIMARY KEY ... NOT ENFORCED

檢查

計算每個資料表中的資料列,如果任何計數有誤,就會停止

👀 預期:

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

您已完成 Cloud Shell 的操作。你可以關閉這個視窗。

6 · 開啟 BigQuery 和查詢編輯器

👉🌐 控制台:按一下輸出內容結尾的連結,或從導覽選單開啟 BigQuery。在左側的「Explorer」窗格中展開專案:一個包含五個資料表的 music 資料集。

「Explorer」窗格,展開音樂:藝人、唱片公司、播放清單項目、播放清單、歌曲

👉🌐 控制台:在 BigQuery Studio 頂端的「新建」列中,按一下「SQL 查詢」。系統會開啟空白的編輯器分頁。

「使用 SQL 查詢建立新資料列」和下方的空白編輯器分頁標籤

請保留這個分頁。這個實驗室中的每個 👉📋 區塊都會顯示在這裡:選取編輯器中的內容,將新區塊貼到該處,然後按一下「執行」。結果會顯示在下方的面板中。

認識資料表

稍後會用到這兩張表格。每個資料表都會將主鍵宣告為 NOT ENFORCED:BigQuery 不會檢查主鍵,但您即將建構的屬性圖需要明確的鍵,才能瞭解識別資料列的依據。最後一個資料表 PlaylistEntries 是接合資料表:如果歌曲位於四個播放清單中,這個資料表就會有四列。整個故事的來龍去脈都在這個表格中。

這些表格會像這樣串連在一起:唱片公司簽約藝人、藝人發行歌曲,以及透過 PlaylistEntries 將歌曲加入播放清單。Cymbal Records 擁有 Ava Sterling 和 Mina Okafor,以及她們的四首歌曲。Northwind Audio 擁有 Kai Nakamura 和一首歌曲「Midnight Drive」。

桌子

列

金鑰

所持內容

標籤

2

label_id

名稱、行銷預算

演出者

3

artist_id

名稱,哪個標籤

歌曲

5

song_id

歌曲名稱、藝人、串流次數

播放清單

4

playlist_id

名稱、追蹤者

PlaylistEntries

10

entry_id

哪些歌曲位於哪些播放清單中

✅ 檢查點: 🎉 ready 在 Cloud Shell 中,檔案總管的 music 下方有五個表格,並開啟空白的查詢編輯器分頁。

3. 建立圖表 - 選項 A:視覺化建模工具

屬性圖形說明資料表的連結方式。您可以在視覺化圖形建模工具中一起點選 (這個步驟需要點選所有項目),也可以編寫 SQL (下一個步驟只需貼上)。兩者都會產生相同的物件,因此請擇一使用,不要同時使用。

1. 建立圖形殼層

👉🌐 控制台:在 BigQuery Studio 的「建立新項目」列中,開啟「AI 和知識」選單,然後點選「圖表」。

👉🌐 控制台:輸入 MusicGraph 做為「圖表名稱」,並輸入 music 做為「資料集內的圖表目的地」。系統會從資料集 (美國) 填入區域。

👉🌐 控制台:在「資料來源」下方,選取五個表格 (藝人、唱片公司、播放清單項目、播放清單、歌曲),然後按一下「建立」。

模型建立頁面:圖形名稱 MusicGraph、資料集 music、勾選五個表格

👀 畫布隨即開啟,顯示五個彩色節點,節點之間沒有任何線條。右側的「詳細資料」面板會列出「節點 (5)」和「邊緣 (0)」。每個節點都已將資料表的主鍵和所有資料欄做為屬性,按一下任一節點即可查看。

畫布,其中有五個節點,詳細資料面板顯示節點 (5) / 邊緣 (0)

2. 繪製四個邊緣

邊緣是外鍵,每個參照都從保存鍵的資料表,指向該鍵所指的資料表。

👉🌐「控制台」- 按一下「新邊緣」。在「選取表格」對話方塊中,選擇 PlaylistEntries 並點按「新增」。在「新增邊緣」面板中:

  1. 將「Name」(名稱) 設定為 EntryToSong。
  2. 按一下「新增主鍵」,然後接受 entry_id。
  3. 在「來源」下方,將「來源節點」設為 PlaylistEntries,然後使用「在節點上新增參照的資料欄」和「在邊緣上新增參照的資料欄」,為兩者選取 entry_id。
  4. 在「目標」下方,將「目標節點」設為「歌曲」,然後為「節點的參照欄」和「邊緣的參照欄」選取 song_id。
  5. 按一下「完成」。

為 EntryToSong 填入的「新增邊框面板」

👉🌐 Console - 再重複三次:

邊緣名稱

桌子

來源節點 → 目標節點

兩側要挑選的資料欄

EntryToPlaylist

PlaylistEntries

PlaylistEntries → Playlists

來源 entry_id,目標 playlist_id

SongToArtist

歌曲

歌曲 → 藝人

來源 song_id,目標 artist_id

ArtistToLabel

演出者

藝人 → 唱片公司

來源 artist_id,目標 label_id

每個邊緣都不要有額外屬性。

👀「詳細資料」面板現在會顯示「邊緣 (4)」,畫布則會顯示鏈結:標籤 ← 藝人 ← 歌曲 ← PlaylistEntries → 播放清單。

畫布,其中有五個節點和四條邊緣,詳細資料顯示邊緣 (4)

3. 新增度量

👉🌐 控制台:按一下「歌曲」節點,然後點選「詳細資料」面板頂端的「編輯」 (鉛筆) 圖示。在標籤的「屬性」下方,依序點選「新增屬性」和「新增欄位」。

👉🌐 控制台:輸入 total_streams 做為「欄位名稱」,然後在「運算式」方塊中輸入以下內容:

MEASURE(SUM(streams))

👉🌐 主控台:依序點按「新增」和「完成」。

新屬性資訊卡:欄位名稱 total_streams,運算式 MEASURE(SUM(streams))

4. 閱讀系統編寫的程式碼,然後發布

👉🌐 控制台:開啟右側面板中的「程式碼」分頁。建模者已為您撰寫 CREATE PROPERTY GRAPH 陳述。捲動至「Songs」節點:其屬性清單現在會以

MEASURE(SUM(streams)) AS `total_streams`

這就是這項功能的全部內容,一行就說完了。這個步驟之後的所有內容,都是關於該行的作用。

「程式碼」分頁,捲動至「歌曲」節點,顯示 MEASURE(SUM(streams)) AS total_streams

👉🌐 控制台 - 點選「發布」。

✅ 檢查點:在 Explorer 中,music 現在有一個包含 MusicGraph 的「圖表」資料夾。點選:五個節點、四條邊緣,以及「程式碼」分頁中的 MEASURE(SUM(streams)) 行。略過下一個步驟,直接前往「SUM 和 AGG 並列」。

4. 建立圖表 - 選項 B:SQL

如果您在模型器中建構圖表,請略過這個步驟。

👉📋 查詢編輯器 - 貼上,然後點選「執行」:

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
  )

👀 結果面板會顯示屬性圖已建立。

編輯器中的 CREATE PROPERTY GRAPH 陳述式,以及下方的成功訊息

朗讀一次

這個圖表有五個節點資料表和四個邊緣資料表。每個節點表格都會命名 KEY 並列出 PROPERTIES。以 MEASURE 開頭的行是新部分:每一行都會將其中一個支援的聚合體包裝在屬性周圍,並為其提供別名 (這是必要做法)。

每個邊緣資料表都是外鍵,拼寫方式如下:SOURCE KEY 在保存鍵的資料表上,DESTINATION KEY 在指向的資料表上。NO PROPERTIES 表示邊緣本身沒有任何內容。

請注意,PlaylistEntries 出現了三次:一次是節點資料表,另外兩次是 EntryToSong 和 EntryToPlaylist 邊緣後方的實體資料表。這是刻意設計,稍後我們會說明原因。

看看你製作的內容

👉🌐 控制台:在「Explorer」窗格中,依序展開 music、「Graphs」和「MusicGraph」。圖表頁面會在畫布上開啟,其中包含五個節點和四條邊緣。按一下節點即可查看屬性,當中會列出指標及其匯總。開啟「程式碼」分頁,即可查看圖片背後的陳述內容。

MusicGraph 頁面:左側為畫布,右側為「程式碼」分頁

✅ 檢查點:music 具有包含 MusicGraph 的「Graphs」資料夾,且「程式碼」分頁會顯示 MEASURE(SUM(streams)) AS total_streams。

5. SUM 和 AGG 並列

這項查詢包含整個程式碼研究室的內容。這兩欄都嘗試從同一個資料表回答相同問題,也就是每個唱片的總串流次數。

該資料表就是 GRAPH_EXPAND 產生的資料表。這個函式會「扁平化」圖表:從一個資料表開始,沿著每個邊緣向外移動,直到所有連線的資料表都並排顯示在單一寬廣的結果中。LEFT JOIN每刊登位置一列,而非每首歌曲一列,且每個資料欄都命名為 TableLabel_property。請先查看該項目,再查詢。

👉📋 查詢編輯器 - 貼上,然後點選「執行」:

SELECT Labels_label_name, Songs_title, Songs_streams, Playlists_playlist_name
FROM GRAPH_EXPAND("music.MusicGraph")
ORDER BY Songs_title, Playlists_playlist_name

👀 預期會有 10 個資料列,PlaylistEntries 中的每個刊登位置各有一個資料列,這正是設定載入的內容。「Neon Summer」佔了其中四個位置 (每個播放清單各一個),且每個播放清單的Songs_streams讀取次數都達到 2,000,000,000 次。這些資料列沒有問題,播放清單確實是四個。但屬於歌曲的資料欄現在會在屬於刊登位置的資料列中重複出現,這就是下一個查詢要評估的整個問題。

現在來比較一下。

👉📋 查詢編輯器 - 貼上,然後點選「執行」:

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

👀 結果:

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

結果格線:Cymbal Records 的 with_sum 為 12,600,000,000,with_agg 為 5,100,000,000

請手動檢查。Cymbal 的四首歌曲分別有 20 億、15 億、12 億和 4 億次串流。也就是 51 億。AGG 是正確的。SUM 的大小是原本的 2.5 倍,而 Northwind 的單一歌曲大小則是原本的 2 倍。

三種新語法

  • GRAPH_EXPAND("music.MusicGraph") 是資料表值函式,會將圖表轉換為一個寬資料表,並將每個邊緣視為 LEFT JOIN。每個資料欄都命名為 TableLabel_property,因此 Songs_streams 是 Songs 資料表中的原始資料欄,而 Songs_total_streams 是您宣告的指標。
  • SUM(Songs_streams) 是針對該寬資料表的普通 SQL,並會繼承扁平化產生的每個重複項目。
  • AGG(Songs_total_streams) 會以宣告的方式評估指標:每 song_id 一次,無論歌曲在寬資料表中佔據多少列。SUM(streams)

✅ 檢查點:兩個標籤、兩欄,且 with_agg 數字與手部數量相符。

6. 為什麼 SUM 會多算

選取一首歌曲,然後看看這些接合點對歌曲有什麼影響。

👉📋 查詢編輯器 - 貼上,然後點選「執行」:

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

👀 結果:

點選 [下一步]

title

小溪

播放清單

更新前 - Songs 資料表

霓虹夏日

2,000,000,000

null

AFTER - joined to playlists

霓虹夏日

2,000,000,000

健身房

AFTER - joined to playlists

霓虹夏日

2,000,000,000

目前熱門

AFTER - joined to playlists

霓虹夏日

2,000,000,000

竄紅流行樂

AFTER - joined to playlists

霓虹夏日

2,000,000,000

Road Trip

結果格線:一個「之前」資料列和四個「之後」資料列,全部都是 2,000,000,000

一列變成四列。串流數量不會變更,而是複製。將副本的播放次數加總:Cymbal Records 的 Neon Summer 在四個播放清單中獲得 20 億次播放,總共是 80 億次;Paper Crown 在兩個播放清單中獲得 15 億次播放,總共是 30 億次;Double Shot 在一個播放清單中獲得 12 億次播放;Slow Arrow 在一個播放清單中獲得 4 億次播放。也就是 126 億,這是 SUM 傳回的數字。Northwind 的 Midnight Drive 位於兩個播放清單中,因此 45 億次播放次數會變成 90 億次。

這是「扇出」,並非聯結中的錯誤。播放清單列是真的。錯誤是將屬於刊登位置的資料列中,屬於歌曲的數字加總。

由於該指標是在「歌曲」節點上與 KEY (song_id) 一起宣告,因此可修正這個問題。關鍵在於紋理。AGG 評估 total_streams 時,系統會針對每個歌曲調性匯總一次,然後再匯總至您分組的任何項目。

異動內容

你以前寫的內容

有測量指標

SUM(streams),在每項需要這項功能的查詢中

MEASURE(SUM(streams))一次,在圖表中

SUM(...) 即可閱讀

AGG(...) 讀取該檔案,且只能讀取該檔案 AGG

三 JOIN 秒

GRAPH_EXPAND(),一個無格式資料表

在聯結前彙整的 CTE

完全沒影響。KEY 決定了粒度

✅ 檢查點:五列資料 (一列是 BEFORE,四列是 AFTER),您可從中重建 126 億筆資料。

7. 規則:只有 AGG 會讀取測量指標

測量指標有自己的類型 MEASURE,且只有一個函式會接受該類型。下列四項查詢會刻意失敗,請逐一執行並閱讀紅色錯誤訊息。這四種說法是大家最常嘗試的,瞭解這些說法可節省後續時間。

👉📋 查詢編輯器 - AGG 位於純文字欄:

SELECT AGG(Songs_streams) FROM GRAPH_EXPAND("music.MusicGraph")

👀 No matching signature for aggregate function AGG ... Argument 1: expected MEASURE, found INT64

編輯器下方的紅色錯誤

👉📋 查詢編輯器 - 沒有 AGG 的指標資料欄:

SELECT Songs_total_streams FROM GRAPH_EXPAND("music.MusicGraph") LIMIT 1

👀 Returning expressions of type MEASURE is not allowed

編輯器下方的紅色錯誤

👉📋 查詢編輯器:GQL 中參照的指標,但從未顯示任何指標 (這是 GQL 查詢,請參閱總覽中的版本附註):

GRAPH music.MusicGraph
MATCH (s:Songs)
RETURN s.total_streams
LIMIT 1

👀 total_streams is not exposed by element type GRAPH_NODE(...)

編輯器下方的紅色錯誤訊息

👉📋 查詢編輯器 - SUM 將滑鼠游標懸停在評估資料欄上,也就是您想使用的資料欄:

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

編輯器下方的紅色錯誤

因此型別系統會為您強制執行規則。測量指標只能透過 GRAPH_EXPAND 顯示,且只能透過 AGG 讀取。先前多算的 126 億次只能來自於加總原始資料欄,絕不會是誤用指標所致。

✅ 檢查點:四個紅色錯誤,且您能指出每個錯誤強制執行的規則。

8. 每個匯總值,以及該指標支援的匯總值

MEASURE() 會包裝六個匯總之一:SUM、AVG、MIN、MAX、COUNT 和 COUNT(DISTINCT)。在「Songs」節點上重新建立圖表,邊緣會保持 NO PROPERTIES,這是邊緣與節點共用實體資料表時,記錄在文件中的最佳做法。

👉📋 查詢編輯器 - 貼上,然後點選「執行」:

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
  )

六項措施的 CREATE PROPERTY GRAPH 執行作業和成功訊息

現在請將所有內容讀回。每個測量值都會經過 AGG,最後一欄顯示的 AGG 結果是可進行算術運算的普通值。圖表剛變更,請先清除「使用快取結果」(「更多」→「查詢設定」)。

👉📋 查詢編輯器 - 貼上,然後點選「執行」:

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

👀 結果:

Labels_label_name

total_streams

avg_streams

min_streams

max_streams

歌曲

藝人

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

七欄結果格線、兩個標籤

每個數字都是根據 Cymbal 的四首歌曲和 Northwind 的一首歌曲計算,而不是根據十個刊登位置列。AVG 尤其會出現錯誤,因為如果將原始資料欄的資料平均分配到每個刊登位置列,Cymbal 的值會變成 15.75 億,這是因為 Neon Summer 的 20 億會計算四次。

因此「將 SUM 換成 AGG」實際上是兩項決策。宣告指標時,您仍可選擇六個匯總函式中的其中一個。讀取指標時,函式一律為 AGG。

✅ 檢查點:每個標籤各一列,每列七個數字,且 streams_per_song 等於 avg_streams。

9. 變更分組,而非指標

同一項指標回答了不同的問題。改為依播放清單分組,而非依標籤分組。

👉📋 查詢編輯器 - 貼上,然後點選「執行」:

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

👀 結果:

Playlists_playlist_name

小溪

歌曲

Road Trip

6,900,000,000

3

健身房

6,500,000,000

2

目前熱門

4,700,000,000

3

竄紅流行樂

3,500,000,000

2

結果格狀檢視畫面,頂端為「Road Trip」6,900,000,000

這兩條 AGG 線條與 SUM 和 AGG 的線條完全相同,只是並排顯示。只有 GROUP BY 會轉移。「Road Trip」播放清單收錄了「Neon Summer」、「Midnight Drive」和「Slow Arrow」,每首歌在播放清單中都算一次,這就是「播放清單的串流次數」的意義。

撰寫該措施的人員已決定一次細節。之後任何人提出的查詢都會沿用這項設定。

✅ 查核點:「哈啦上路」以 69 億次觀看次數位居榜首。

10. 查看 GRAPH_EXPAND 的輸出結果

您不必執行 GRAPH_EXPAND 即可瞭解形狀。BQ.SHOW_GRAPH_EXPAND_SCHEMA 系統程序會將資料欄清單寫入變數。

👉📋 查詢編輯器 - 貼上所有三行,然後按一下「執行」:

DECLARE schema STRING DEFAULT '';
CALL BQ.SHOW_GRAPH_EXPAND_SCHEMA('music.MusicGraph', schema);
SELECT schema;

👀 結果是 JSON 字串。每個欄位都有名稱、類型和模式,且每個指標資料欄都會帶有 "is_measure": true。您剛建構的圖表會提供下列資訊:

名稱

類型

is_measure

Songs_title

STRING

Songs_streams

INTEGER

Songs_total_streams

INTEGER

true

Songs_avg_streams

FLOAT

true

Songs_distinct_artists

INTEGER

true

PlaylistEntries_placement_count

INTEGER

true

單一 JSON 儲存格,展開後可顯示 is_measure 為 true

您在屬性中設定的任何說明或同義字也會顯示在這裡。選用的即時通訊步驟會顯示誰讀取這些內容。

✅ 檢查點:JSON 字串,其中每個以 MEASURE 宣告的資料欄都有 is_measure。

11. GRAPH_EXPAND 需要圖譜形狀的哪些資訊

這個步驟沒有要執行的內容,只要閱讀即可。GRAPH_EXPAND 會從一個資料表開始,沿著邊緣向外擴展,以 LEFT JOIN 鏈結建構寬資料表。這三項規則是從該原則衍生而來,而 MusicGraph 符合所有規則。

GRAPH_EXPAND 形狀需要 PlaylistEntries 做為單一根目錄、四個多對一邊緣向外,以及升格為節點的多對多 Songs-Playlists 配對

只能有一個根節點資料表。根是節點資料表,其鍵不會出現在任何其他資料表中,也就是沒有任何邊指向的節點。在 MusicGraph 中,PlaylistEntries 是兩條邊的來源,但不是任何邊的目的地。寬表格有 10 列,每列代表一個刊登位置。

每個邊緣都是多對一,從來源到目的地。每個項目都有一首歌曲和一個播放清單,每首歌曲有一位藝人,每位藝人有一個唱片公司。因此,寬表格絕不會超出根目錄本身的列。根目錄無法存取的資料不會顯示:如果歌曲沒有刊登位置,就不會出現在廣泛資料表中。

多對多關係會成為節點。歌曲和播放清單之間是多對多關係。如果您將接合資料表宣告為從歌曲到播放清單的單一邊緣,GRAPH_EXPAND 會忽略該資料表,因為這類邊緣不明確。由於沒有可用的邊緣,GRAPH_EXPAND 會失敗。將 PlaylistEntries 升格為節點資料表,並從中建立兩個多對一邊緣,是記錄在案的模式,也是您建構圖表時採用的做法。

12. (選用) 使用 GQL 查詢路徑

目前為止,每個問題都有一個答案編號。這個則不會。「Cymbal 的串流在何處觸及聽眾?」是關於圖表中路徑的問題,總和無法回答這個問題,因為在您加總時,路徑就消失了。

1. 詢問串流的播放位置

👉📋 查詢編輯器 - 貼上,然後點選「執行」:

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

👀 預計會有四個播放清單:

pl.playlist_name

pl.followers

streams_reaching_this_playlist

歌曲

目前熱門

35,000,000

4,700,000,000

Double Shot、Neon Summer、Paper Crown

竄紅流行樂

2,000,000

3,500,000,000

Neon Summer、Paper Crown

Road Trip

5,000,000

2,400,000,000

霓虹夏日、慢速箭頭

健身房

3,000,000

2,000,000,000

霓虹夏日

GQL 結果:四個播放清單,以及每個播放清單的串流次數

請將 MATCH 行視為一個句子:從唱片公司開始,往回走到藝人,再往回走到藝人的歌曲,然後往回走到這些歌曲所在的播放清單項目,最後往前走到播放清單。箭頭指向邊緣的宣告方式;<- 則會向後走一步。

現在請加總第三欄的數字。126 億:這是步驟四中 SUM 給你的數字,也就是錯誤的數字。

這就是正確的。當時的問題是 Cymbal 的串流次數,無論歌曲出現在多少播放清單中,都只會計算一次。這個問題就是這些串流的觸及範圍,而一首歌曲在四個播放清單上,確實觸及了四個目標對象。GRAPH_EXPAND 產生的重複內容,其中一個是問題,另一個是答案。AGG 從來不是要避免重複,而是要讓算術與問題相符。

2. 傳回路徑本身

取消匯總,然後要求路線。

👉📋 查詢編輯器 - 貼上,然後點選「執行」:

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 = 會命名整個相符項目,而 TO_JSON 會算繪該項目。

👀 預期會有 8 列,以及一個 path 欄。每個儲存格都是節點和邊緣的 JSON 陣列,沿著一條路線,每個節點都攜帶 labels 和 properties。

8 個資料列,每個資料列都是 JSON 路徑,結果窗格中含有「圖表」分頁

四首歌曲共八列,因為每個刊登位置都有路徑,而非每首歌曲都有。

3. 開啟「圖表」分頁

👉🌐 主控台:在結果上方點選「圖表」。

只有在結果包含圖表元素時,系統才會顯示這個分頁。先前的查詢傳回數字,因此沒有「圖表」分頁;這次的查詢傳回路徑,因此有「圖表」分頁。

「圖表」分頁,以強制版面配置繪製 Cymbal 的子圖

您會看到以強制版面配置繪製的 Cymbal 圖表角落,以及每個標籤的節點和邊緣計數。拖曳節點即可拉開版面配置;按一下節點即可讀取其屬性。

✅ 檢查點:第一個查詢的第三欄總和為 126 億,第二個查詢會傳回 8 個路徑,「圖表」分頁會繪製這些路徑。

13. (選用) 與圖表對話

這個步驟不涉及 SQL。BigQuery 資料代理可將圖表做為知識來源,且文件指出這些代理會使用多層級匯總的指標。我們來看看是否真是如此。

1. 建立代理

👉🌐 控制台:在左側的 BigQuery 導覽選單中,依序點選「代理程式」、「代理程式目錄」和「建立代理程式」。

👉🌐 控制台:在「代理名稱」中輸入 Music graph agent,並在「代理說明」中輸入:

Ask questions about labels, artists, songs and playlists in the music property graph.

👉🌐 控制台:在「知識來源」下方,按一下「新增來源」。在「選取來源」對話方塊中,依序展開專案、music、「圖表」,勾選「MusicGraph」,然後按一下「確認」。

👀「新增來源」按鈕會變成灰色。代理最多可保留一個圖表,且無法混用圖表和表格。

「選取來源」對話方塊,其中「MusicGraph」已勾選,且「已選取」顯示為「1」

👉🌐 管理中心 - 將「區域」保留為圖表位置設定的值。依序點選「儲存」和「發布」。在「發布管道」面板中,按一下「發布代理」並關閉確認視窗。

2. 提問

👉🌐 主控台:按一下「建立對話」。系統會開啟即時通訊頁面。在底部的「提出問題」方塊中輸入下列內容,然後按下 Enter 鍵:

For each label, show total streams and how many playlists their songs are on

👀 代理程式會傳回表格和一句摘要:

label_name

total_streams

playlist_placements

Cymbal Records

5,100,000,000

8

Northwind Audio

4,500,000,000

2

代理的回覆:表格和一句摘要

51 億美元。沒有人告訴代理程式有關擴散傳遞功能,而且代理程式也沒有落入擴散傳遞功能。

3. 閱讀系統撰寫的查詢

👉🌐 控制台:在導覽選單中,依序點選「Jobs explorer」和最新工作。標籤包括 ca-bq-job: true 和 data-agent-id,其中包含代理程式的 ID,查詢內容如下:

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

工作探索工具:工作的標籤 (ca-bq-job、data-agent-id) 和 SQL

因為讀取的結構定義中含有這些指標,因此會自行使用 GRAPH_EXPAND 和 AGG。代理的說明中未提及這些項目。

✅ 檢查點:聊天室回覆中為 51 億,且作業的 SQL 中為 AGG(...)。

14. 清理

👉💻 Cloud Shell - 捨棄資料集、資料表和屬性圖:

cd ~/bq-graph-measures-lab
./cleanup.sh

👀 預期 ✓ dropped YOUR_PROJECT_ID.music (tables and graph)。

如果您建立了選用資料代理,請在控制台的「Agents」→「Agent catalog」下方刪除。如果您./setup_project.sh是為了這個實驗室建立專案,最徹底的清除方式就是關閉整個專案,專案 ID 位於 ~/project_id.txt。

15. 恭喜

您宣告了一行 MEASURE(SUM(streams)),將 126 億改為 51 億,這項變更會影響您和之後對該圖表執行的所有查詢 (包括代理程式編寫的查詢)。

您學到的內容

  • 測量值是在節點上宣告的匯總,位於設定其粒度的 KEY 旁。
  • GRAPH_EXPAND 會將圖表攤平為一個寬表格,其中包含 TableLabel_property 欄。
  • AGG 是唯一會讀取指標的函式,型別系統會以四種不同方式強制執行這項操作。
  • 共有六個匯總值,而 AGG 結果是可除以的普通值。
  • 變更 GROUP BY 會重新詢問問題,但不會影響測量結果。
  • GRAPH_EXPAND 想要一個根、多對一的邊緣,以及升級為節點的交接點。

決策表

問題

原因

修正

總金額過高

SUM 展開的資料欄

宣告測量值,並使用 AGG 讀取

「expected MEASURE, found INT64」(預期為 MEASURE,但找到 INT64)

AGG 在一般資料欄上

使用 SUM,或宣告測量值

「Returning expressions of type MEASURE is not allowed」(不允許傳回 MEASURE 類型的運算式)

沒有 AGG 的測量欄

包裝:AGG(...)

「not exposed by element type」(元素類型未公開)

GQL 參照的測量指標

僅測量落後 GRAPH_EXPAND 的直播

GRAPH_EXPAND 忽略邊緣或失敗

以邊緣形式模擬的交會點

將接合表升級為節點

變更圖表後的舊號碼

快取結果

取消勾選「使用快取結果」

我們刻意未涵蓋的主題

屬性的說明和同義詞、資料代理的已驗證查詢和詞彙表、超過一個 MATCH 的 GQL、多個圖譜的測量指標。每個都是獨立的實驗室。

瞭解詳情