Começar a usar as medidas de gráfico do BigQuery

1. Visão geral

A maioria dos bugs de SQL que sobrevivem à revisão de código são bugs de agregação. Um número está correto na tabela em que está, uma junção o copia e o total está errado.

Com o BigQuery Graph, você descreve como as tabelas se conectam uma vez, como um gráfico de propriedades, e depois consulta as conexões. As medidas de gráfico adicionam mais uma coisa a essa descrição: a própria agregação. Você declara MEASURE(SUM(streams)) no nó que possui o número, e toda consulta que lê o gráfico recebe o total correto no nível certo. Não há truque de GROUP BY nem CTE que alguém precise lembrar.

Neste codelab, você vai criar um catálogo de músicas com cinco tabelas, adicionar uma métrica a ele e ver a mesma pergunta retornar duas respostas diferentes: 12,6 bilhões com SUM e 5,1 bilhões com AGG. A lacuna é o formato do catálogo: uma música que está em quatro playlists se torna quatro linhas quando o gráfico é achatado, e SUM adiciona todas as quatro. Em seguida, você aprende as regras que tornam a segunda opção correta.

Uma linha "Songs" copiada em quatro linhas de posição: SUM adiciona as cópias, AGG recolhe em "song_id".

Onde você vai digitar

Este laboratório usa exatamente dois lugares, nesta ordem:

onde

o que você faz lá

1

Terminal do Cloud Shell

alguns comandos, apenas na etapa Configuração

2

Console do BigQuery

Todo o resto: colar consultas no editor de consultas, clicar no modelador de gráficos, conversar com um agente

Cada instrução é marcada para que você sempre saiba o que ela significa:

  • 👉💻 Cloud Shell: digite isso no terminal do Cloud Shell.
  • 👉📋 Editor de consultas: cole isso no editor de consultas do BigQuery e clique em Executar.
  • 👉🌐 Console: clique no console do BigQuery. Não digite nada, a menos que a etapa diga o contrário.
  • 👀: confira o resultado.

O que você vai aprender

  • Como declarar uma métrica em uma tabela de nós no modelador gráfico visual ou em SQL
  • Como o GRAPH_EXPAND nivela um gráfico em uma tabela ampla
  • Por que AGG é a única função que pode ler uma métrica e o que todas as outras tentativas dizem
  • Os seis agregados que uma métrica aceita e como fazer cálculos aritméticos com eles
  • Como uma medida responde a uma pergunta agrupada de forma diferente sem mudanças
  • Opcional: como a GQL e a guia "Gráfico" respondem a uma pergunta que um total não consegue, e como um agente de dados do BigQuery usa suas métricas sem que você precise informá-las.

O que é necessário

  • Uma Conta do Google com faturamento disponível e um navegador. Você não precisa de um projeto na nuvem do Google Cloud de imediato. A configuração cria um para você.
  • Somente para a etapa de chat opcional: a API Gemini Data Analytics ativada e o papel Criador do agente de dados do Gemini Data Analytics.

Não é necessário instalar nada na sua máquina. Tudo é executado no Cloud Shell e no console do BigQuery.

Status e custo do produto

O BigQuery Graph está disponível para todos. As medidas de gráfico, o modelador de gráficos visuais, a visualização de gráficos e o uso de um gráfico como fonte de conhecimento de um agente de dados estão em prévia, cobertos pelos Termos de ofertas pré-GA.

GRAPH_EXPAND e AGG são executados com preços sob demanda. As consultas GQL (a etapa opcional de caminho) exigem uma reserva que use a edição Enterprise ou Enterprise Plus, de acordo com a documentação. Por isso, essa etapa é opcional.

O conjunto de dados tem alguns kilobytes. Com o sistema de preços sob demanda, cada consulta é faturada com o mínimo de 10 MB. Assim, todo o codelab custa uma fração de um centavo.

2. Configuração

Esta é a única etapa que usa o Cloud Shell. Ele cria um projeto, ativa o faturamento nele e cria as tabelas brutas. O gráfico, a métrica e todas as consultas podem ser executados depois no console do BigQuery.

Há uma coisa que este laboratório não pode oferecer: um projeto na nuvem do Google Cloud com faturamento ativado. A etapa 1 cria uma conta que pode pagar por ele, e a etapa 4 transforma essa conta em um projeto. Faça isso nessa ordem. Cada etapa depois da 4 lê o projeto que a etapa 4 cria.

1 · Receber uma conta com faturamento (~1 min)

👉🌐 Faça isso antes de qualquer outra coisa. Faça login com uma Conta do Google que tenha o faturamento ativado. Qualquer uma delas funciona. Se não tiver, inicie um teste sem custo financeiro. Ele oferece uma conta de faturamento, que é tudo o que a etapa 4 precisa.

2 · Abra o Cloud Shell (~1 min)

👉🌐 Console: clique em Ativar o Cloud Shell na parte de cima do console do Google Cloud. É o ícone em forma de terminal no cabeçalho. Um terminal é aberto na parte de baixo da página.

Ativar o Cloud Shell no cabeçalho do console do Google Cloud

👉🌐 Console: se for necessário autorizar em algum momento hoje, clique em Autorizar para continuar.

👉💻 Cloud Shell: verifique com qual conta o Cloud Shell está conectado:

gcloud auth list

👀 Espere que sua conta seja marcada com um * e que seja a mesma conta em que você fez login na etapa 1. Caso contrário, execute gcloud auth login e escolha a opção correta.

3 · Faça o laboratório (~1 min)

👉💻 Cloud Shell: clone o repositório:

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

4 · Crie seu projeto (~2 min)

👉💻 Cloud Shell: um script encontra sua conta de faturamento, cria um projeto nela e aponta o Cloud Shell para esse projeto:

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

👀 Espere um ✓ para a conta de faturamento escolhida, um ✓ para o projeto criado e uma finalização como:

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

bq-graph-4271 é o ID do projeto, que terá dígitos diferentes. Quatro coisas acontecem lá:

faturamento

usa a conta [YYYY-MM-DD] GDP Credit: mais recente, se você tiver uma, e qualquer outra conta de faturamento aberta, caso contrário.

project

cria o bq-graph-XXXX e vincula a conta de faturamento a ele

seleciona

grava o ID em ~/project_id.txt e executa gcloud config set project. Portanto, nada depois disso pede que você digite o ID.

waits

faz pesquisas até que o novo projeto seja autorizado a veicular, por até dois minutos

🌐 O mesmo projeto agora está no console. O ID dele fica no card Informações do projeto no painel:

O ID do projeto no painel do console

5 · Criar o conjunto de dados (~3 min)

👉💻 Cloud Shell: mais um script cria as tabelas:

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

O script imprime cada etapa à medida que é executado. O que ele faz, em ordem:

project

lê o projeto de gcloud config e se recusa a continuar sem um

API

ativa o bigquery.googleapis.com

dataset

cria o conjunto de dados music na multirregião dos EUA e cinco tabelas, cada uma com um PRIMARY KEY ... NOT ENFORCED

check

conta as linhas em todas as tabelas e para se alguma contagem estiver errada

👀 Expect:

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

Você terminou de usar o Cloud Shell. Você pode fechar.

6 · Abrir o BigQuery e um editor de consultas

👉🌐 Console: clique no link no final da saída ou abra o BigQuery no menu de navegação. No painel Explorer à esquerda, expanda seu projeto: um conjunto de dados music com cinco tabelas.

Painel do Explorer, música expandida: Artists, Labels, PlaylistEntries, Playlists, Songs

👉🌐 Console: na parte de cima do BigQuery Studio, na linha Criar novo, clique em Consulta SQL. Uma guia vazia do editor será aberta.

a opção "Criar nova linha com consulta SQL" e a guia do editor vazia abaixo dela

Mantenha esta guia. Todos os blocos 👉📋 deste laboratório vão aqui:selecione o que estiver no editor, cole o novo bloco por cima e clique em Executar. O resultado aparece no painel abaixo.

Conheça as tabelas

Duas coisas sobre essas tabelas são importantes mais tarde. Cada tabela declara sua chave primária como NOT ENFORCED. O BigQuery não verifica isso, mas o gráfico de propriedades que você vai criar precisa de uma chave explícita para saber o que identifica uma linha. A última tabela, PlaylistEntries, é uma tabela de junção: uma música que está em quatro playlists tem quatro linhas nela. É nessa tabela que toda a história acontece.

As tabelas são encadeadas assim: uma gravadora assina com artistas, um artista lança músicas, uma música é colocada em playlists usando PlaylistEntries. A Cymbal Records é proprietária de Ava Sterling e Mina Okafor, e, por isso, de quatro músicas. A Northwind Audio é proprietária de Kai Nakamura e de uma música, "Midnight Drive".

tabela

linhas

chave

o que ele contém

Rótulos

2

label_id

name, marketing budget

Artistas

3

artist_id

nome, qual rótulo

Músicas

5

song_id

título, artista, streams

Playlists

4

playlist_id

name, followers

PlaylistEntries

10

entry_id

qual música está em qual playlist

✅ Checkpoint : 🎉 ready no Cloud Shell, cinco tabelas em music no Explorer e uma guia vazia do editor de consultas aberta.

3. Criar o gráfico: opção A (modelador visual)

Um gráfico de propriedades é uma descrição de como as tabelas se conectam. Você pode clicar nele no modelador de gráficos visuais (esta etapa, todos os cliques) ou escrever como SQL (a próxima etapa, uma colagem). Ambos produzem o mesmo objeto. Faça um ou outro, não os dois.

1. Criar o shell do gráfico

👉🌐 Console: no BigQuery Studio, na linha Criar novo, abra o menu IA e conhecimento e clique em Gráfico.

👉🌐 Console: insira MusicGraph como o Nome do gráfico e music como o Destino do gráfico no conjunto de dados. A região é preenchida com base no conjunto de dados (EUA).

👉🌐 Console: em Fontes de dados, selecione as cinco tabelas (Artists, Labels, PlaylistEntries, Playlists, Songs) e clique em Criar.

Página de criação do modelador: nome do gráfico MusicGraph, conjunto de dados music, cinco tabelas marcadas

👀 A tela abre com cinco nós coloridos e sem linhas entre eles. O painel Detalhes à direita lista Nós (5) e Arestas (0). Cada nó já tem a chave primária da tabela e todas as colunas como propriedades. Clique em qualquer nó para conferir.

tela com cinco nós, painel "Detalhes" mostrando "Nós (5) / Arestas (0)"

2. Desenhe as quatro bordas

Uma aresta é uma chave estrangeira desenhada. Cada uma vai da tabela que contém a chave para a tabela a que ela aponta.

👉🌐 Console: clique em Nova borda. Na caixa de diálogo Selecionar tabela, escolha PlaylistEntries e clique em Adicionar. No painel Adicionar aresta:

  1. Defina o Nome como EntryToSong.
  2. Clique em Adicionar chave primária e aceite entry_id.
  3. Em Origem, defina Nó de origem como PlaylistEntries. Em seguida, use Adicionar colunas referenciadas ao nó e Adicionar colunas referenciadas na aresta para escolher entry_id em ambos.
  4. Em Destino, defina Nó de destino como "Músicas" e escolha song_id para Colunas referenciadas no nó e Colunas referenciadas na aresta.
  5. Clique em Concluído.

o painel "Adicionar borda" preenchido para EntryToSong

👉🌐 Console: repita mais três vezes:

nome da borda

tabela

nó de origem → nó de destino

a coluna para escolher nos dois lados

EntryToPlaylist

PlaylistEntries

PlaylistEntries → Playlists

origem entry_id, destino playlist_id

SongToArtist

Músicas

Músicas → Artistas

origem song_id, destino artist_id

ArtistToLabel

Artistas

Artistas → Gravadoras

origem artist_id, destino label_id

Deixe todas as arestas sem propriedades extras.

👀 O painel "Detalhes" agora mostra Arestas (4), e a tela mostra a cadeia: Labels ← Artists ← Songs ← PlaylistEntries → Playlists.

tela com cinco nós e quatro arestas, detalhes mostrando arestas (4)

3. Adicionar a medida

👉🌐 Console: clique no nó Músicas e depois no ícone Editar (lápis) na parte de cima do painel "Detalhes". Em Propriedades do rótulo, clique em Adicionar propriedade e depois em Adicionar campo.

👉🌐 Console: insira total_streams como o Nome do campo e digite isso na caixa Expressão:

MEASURE(SUM(streams))

👉🌐 Console: clique em Adicionar e em Concluído.

o card "Nova propriedade": nome do campo "total_streams", expressão "MEASURE(SUM(streams))"

4. Leia o código que ele escreveu e publique

👉🌐 Console: abra a guia Código no painel à direita. O modelador escreveu a instrução CREATE PROPERTY GRAPH para você. Role até o nó "Músicas": a lista de propriedades agora termina com

MEASURE(SUM(streams)) AS `total_streams`

Esse é o recurso completo, em uma linha. Tudo depois dessa etapa é sobre o que essa linha faz.

a guia "Código", role até o nó "Músicas", MEASURE(SUM(streams)) AS total_streams visível

👉🌐 Console: clique em Publicar.

✅ Checkpoint:no Explorer, music agora tem uma pasta Gráficos que contém MusicGraph. Clique nele: cinco nós, quatro arestas e a linha MEASURE(SUM(streams)) na guia "Código". Pule a próxima etapa e acesse SOMA e AGG, lado a lado.

4. Criar o gráfico — Opção B: SQL

Pule esta etapa se você criou o gráfico no modelador.

👉📋 Editor de consultas: cole e clique em Executar:

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
  )

👀 O painel de resultados informa que o gráfico de propriedades foi criado.

a instrução CREATE PROPERTY GRAPH no editor e a mensagem de sucesso abaixo

Ler uma vez

O gráfico tem cinco tabelas de nós e quatro tabelas de arestas. Cada tabela de nós nomeia o KEY e lista o PROPERTIES. As linhas que começam com MEASURE são a nova parte: cada uma envolve um dos agregados compatíveis em uma propriedade e atribui um alias a ela, o que é obrigatório.

Cada tabela de aresta é uma chave externa, explicada assim: SOURCE KEY na tabela que contém a chave e DESTINATION KEY na tabela para onde ela aponta. NO PROPERTIES significa que a aresta não carrega nada próprio.

Observe que PlaylistEntries aparece três vezes: uma como uma tabela de nós e mais duas como a tabela física por trás das arestas EntryToSong e EntryToPlaylist. Isso é proposital, e vamos explicar o motivo mais tarde.

Olha só o que você fez

👉🌐 Console: no painel Explorer, expanda music, depois Gráficos e clique em MusicGraph. A página de gráfico é aberta em uma tela com cinco nós e quatro arestas. Clique em um nó para conferir as propriedades dele. As medidas são listadas com o agregado. Abra a guia Código para ver a declaração por trás da imagem.

a página do MusicGraph: tela à esquerda, guia "Código" à direita

✅ Ponto de verificação: music tem uma pasta Gráficos que contém MusicGraph, e a guia "Código" mostra MEASURE(SUM(streams)) AS total_streams.

5. SUM e AGG lado a lado

Este é o codelab inteiro em uma consulta. As duas colunas tentam responder à mesma pergunta (total de transmissões por rótulo) da mesma tabela.

Essa é a tabela que o GRAPH_EXPAND gera. Ele achata o gráfico: começa em uma tabela e segue cada aresta para fora como um LEFT JOIN, até que todas as tabelas conectadas fiquem lado a lado em um único resultado amplo. Uma linha por posição, não uma por música, e todas as colunas nomeadas TableLabel_property. Analise antes de consultar.

👉📋 Editor de consultas: cole e clique em Executar:

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

👀 Espere 10 linhas, uma para cada posição em PlaylistEntries, que é exatamente o que a configuração carregou. O Neon Summer ocupa quatro delas, uma por playlist em que está, e Songs_streams tem 2.000.000.000 em cada uma. Não há nada de errado com essas linhas. As playlists são quatro mesmo. Mas uma coluna que pertence a uma música agora é repetida em linhas que pertencem a posições, e esse é o problema que a próxima consulta mede.

Agora a comparação.

👉📋 Editor de consultas: cole e clique em Executar:

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

👀 Resultado:

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

a grade de resultados: with_sum 12.600.000.000 e with_agg 5.100.000.000 para a Cymbal Records

Verifique manualmente. As quatro músicas do Cymbal têm 2 bilhões, 1,5 bilhão, 1,2 bilhão e 0,4 bilhão de streams. Isso é 5,1 bilhões. AGG está correto. SUM é duas vezes e meia maior, e a única música da Northwind dobrou.

Três novas sintaxes

  • GRAPH_EXPAND("music.MusicGraph") é uma função com valor de tabela que transforma o gráfico em uma tabela ampla, seguindo cada aresta como um LEFT JOIN. Todas as colunas são chamadas de TableLabel_property. Portanto, Songs_streams é a coluna bruta da tabela "Músicas", e Songs_total_streams é a métrica que você declarou.
  • SUM(Songs_streams) é um SQL comum nessa tabela ampla e herda todos os duplicados produzidos pelo nivelamento.
  • O AGG(Songs_total_streams) avalia a métrica da maneira como ela foi declarada: SUM(streams) uma vez por song_id, não importa quantas linhas uma música ocupe na tabela ampla.

✅ Ponto de verificação:dois rótulos, duas colunas e os números with_agg correspondem à contagem manual.

6. Por que a função SUM faz contagens excessivas

Pegue uma música e veja o que essas junções fazem com ela.

👉📋 Editor de consultas: cole e clique em Executar:

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

👀 Resultado:

etapa

título

de aplicativos.

playlist

ANTES: a tabela "Songs"

Verão neon

2.000.000.000

null

DEPOIS: adicionado às playlists

Neon Summer

2.000.000.000

Gym Pump

DEPOIS: adicionado às playlists

Neon Summer

2.000.000.000

Em alta agora

DEPOIS: adicionado às playlists

Neon Summer

2.000.000.000

Rising Pop

DEPOIS: adicionado às playlists

Neon Summer

2.000.000.000

Na estrada

a grade de resultados: uma linha BEFORE e quatro linhas AFTER, todas com 2.000.000.000

Uma linha se tornou quatro. A contagem de transmissões não mudou, ela foi copiada. Some o que as cópias fazem pela Cymbal Records: Neon Summer 2.0 bilhões em quatro playlists é 8,0, Paper Crown 1,5 bilhão em duas é 3,0, Double Shot 1,2 em uma, Slow Arrow 0,4 em uma. Esse é o número 12,6 bilhões, o número SUM retornado. "Midnight Drive", da Northwind, está em duas playlists, então 4,5 bilhões se tornaram 9 bilhões.

Isso é distribuição de dados e não um bug na junção. As linhas da playlist são reais. O erro é somar um número que pertence a uma música em linhas que pertencem a posições.

A medida corrige isso porque foi declarada no nó "Songs" junto com KEY (song_id). A chave é a granularidade. Quando AGG avalia total_streams, ele agrega uma vez por chave de música e só então faz o resumo de acordo com o que você agrupou.

O que mudou

Você costumava escrever

Com uma medida

SUM(streams) em todas as consultas que precisam dele

MEASURE(SUM(streams)) uma vez no gráfico

SUM(...) para ler

AGG(...) para ler e apenas AGG

Três JOINs

GRAPH_EXPAND(), uma tabela fixa

Uma CTE que agrega antes de fazer a junção

Nada O KEY decide a granularidade

✅ Checkpoint:cinco linhas (uma ANTES, quatro DEPOIS), e você pode reconstruir 12,6 bilhões com elas.

7. A regra: somente AGG lê uma métrica

As métricas têm um tipo próprio, MEASURE, e exatamente uma função as aceita. As quatro consultas abaixo falham de propósito. Execute cada uma delas e leia o erro em vermelho. Essas são as quatro maneiras que todo mundo tenta primeiro, e saber o que elas dizem economiza tempo depois.

👉📋 Editor de consultas — AGG em uma coluna simples:

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

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

o erro vermelho abaixo do editor

👉📋 Editor de consultas: uma coluna de métrica sem AGG:

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

👀 Returning expressions of type MEASURE is not allowed

o erro vermelho abaixo do editor

👉📋 Editor de consultas: uma métrica referenciada em GQL, que nunca vê métricas (esta é uma consulta GQL. Consulte a nota de edição na visão geral):

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

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

o erro vermelho abaixo do editor

👉📋 Editor de consultas: SUM em uma coluna de métricas, a mais tentadora:

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

o erro vermelho abaixo do editor

Assim, o sistema de tipos aplica a regra para você. Uma métrica só fica visível no GRAPH_EXPAND e pode ser lida no AGG. Os 12,6 bilhões superestimados de antes só podem vir da soma da coluna bruta, nunca do mau uso da métrica.

✅ Checkpoint:quatro erros vermelhos, e você pode dizer qual regra cada um está aplicando.

8. Cada agregação que uma métrica aceita

MEASURE() envolve um de seis agregados: SUM, AVG, MIN, MAX, COUNT e COUNT(DISTINCT). Recrie o gráfico com todos os seis no nó "Músicas". As arestas permanecem NO PROPERTIES, que é a prática recomendada documentada quando uma aresta compartilha a tabela física com um nó.

👉📋 Editor de consultas: cole e clique em Executar:

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
  )

a execução do CREATE PROPERTY GRAPH de seis métricas e a mensagem de sucesso

Agora, leia todas elas. Todas as medidas passam por AGG, e a última coluna mostra que os resultados de AGG são valores comuns com que você pode fazer cálculos aritméticos. O gráfico acabou de mudar. Portanto, primeiro desmarque Usar resultados em cache (Mais → Configurações de consulta).

👉📋 Editor de consultas: cole e clique em Executar:

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

👀 Resultado:

Labels_label_name

total_streams

avg_streams

min_streams

max_streams

músicas

artistas

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

a grade de resultados de sete colunas, os dois rótulos

Cada número é calculado em quatro músicas para Cymbal e uma para Northwind, não nas dez linhas de posição. AVG, em particular, teria sido errado de outra forma: a média da coluna bruta nas linhas de posição dá 1,575 bilhão para Cymbal, porque os 2 bilhões de Neon Summer são contados quatro vezes.

Portanto, "trocar SUM por AGG" são duas decisões. Ao declarar a métrica, você ainda escolhe qual dos seis agregados ela é. Ao ler, a função é sempre AGG.

✅ Checkpoint:uma linha por marcador, sete números cada e streams_per_song igual a avg_streams.

9. Mude o agrupamento, não a métrica

A mesma métrica responde a uma pergunta diferente. Agrupe por playlist em vez de rótulo.

👉📋 Editor de consultas: cole e clique em Executar:

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

👀 Resultado:

Playlists_playlist_name

de aplicativos.

músicas

Na estrada

6.900.000.000

3

Gym Pump

6.500.000.000

2

Em alta agora

4.700.000.000

3

Rising Pop

3.500.000.000

2

a grade de resultados, Viagem de carro 6.900.000.000 na parte de cima

As duas linhas AGG são exatamente as mesmas de SUM e AGG, lado a lado. Somente o GROUP BY foi movido. A playlist Road Trip tem Neon Summer, Midnight Drive e Slow Arrow, e cada música conta uma vez dentro dela. É exatamente isso que "streams que chegam a esta playlist" significa.

A pessoa que escreveu a métrica decidiu o nível de detalhe uma vez. Todas as consultas posteriores, de qualquer pessoa, herdam essa configuração.

✅ Checkpoint:Road Trip no topo com 6,9 bilhões.

10. Confira o que a GRAPH_EXPAND oferece

Não é necessário executar GRAPH_EXPAND para aprender o formato dele. O procedimento do sistema BQ.SHOW_GRAPH_EXPAND_SCHEMA grava a lista de colunas em uma variável.

👉📋 Editor de consultas: cole as três linhas e clique em Executar:

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

👀 O resultado é uma string JSON. Cada campo tem um nome, um tipo e um modo, e cada coluna de métrica carrega "is_measure": true. Para o gráfico que você acabou de criar, você recebe estes dados, entre outros:

nome

tipo

is_measure

Songs_title

STRING

Songs_streams

INTEGER

Songs_total_streams

INTEGER

verdadeiro

Songs_avg_streams

FLOAT

verdadeiro

Songs_distinct_artists

INTEGER

verdadeiro

PlaylistEntries_placement_count

INTEGER

verdadeiro

a única célula JSON, expandida o suficiente para mostrar "is_measure" como "true"

Qualquer descrição ou sinônimo definido em uma propriedade também aparece aqui. A etapa de chat opcional mostra quem lê essas informações.

✅ Checkpoint:uma string JSON com is_measure em todas as colunas declaradas com MEASURE.

11. O que o GRAPH_EXPAND precisa da forma de um gráfico

Não há nada para executar nesta etapa, apenas leia. O GRAPH_EXPAND cria a tabela ampla com uma cadeia de LEFT JOINs, começando em uma tabela e seguindo as bordas para fora. Três regras decorrem disso, e o MusicGraph atende a todas elas.

o formato GRAPH_EXPAND precisa de: PlaylistEntries como a única raiz, quatro arestas de muitos para um para fora e o par de músicas e playlists de muitos para muitos promovido a um nó

Exatamente uma tabela de nós raiz. A raiz é a tabela de nós cuja chave não aparece em nenhuma outra tabela, ou seja, aquela a que nenhuma aresta aponta. No MusicGraph, esse nó é PlaylistEntries: a origem de duas arestas e o destino de nenhuma. A tabela ampla tem 10 linhas, uma por posição.

Cada aresta é de muitos para um, da origem para o destino. Cada entrada tem uma música e uma playlist, cada música tem um artista, e cada artista tem uma gravadora. É por isso que a tabela ampla nunca se estende além das linhas da raiz. Os dados que a raiz não pode alcançar não aparecem: uma música sem canais não apareceria na tabela ampla.

As relações de muitos para muitos se tornam um nó. As músicas e playlists são de muitos para muitos. Se você declarou a tabela de junção como uma única aresta de "Músicas" para "Playlists", o GRAPH_EXPAND a ignoraria por ser ambígua. Sem arestas utilizáveis, ele falharia. Promover PlaylistEntries a uma tabela de nós com muitas arestas de muitos para um é o padrão documentado, e foi o que você fez ao criar o gráfico.

12. (OPCIONAL) Caminhos com GQL

Todas as perguntas até agora tiveram um número como resposta. Este não. Onde as transmissões do Cymbal alcançam os ouvintes? é uma pergunta sobre rotas no gráfico, e um total não pode responder a ela. Quando você soma, a rota desaparece.

1. Perguntar onde as transmissões são exibidas

👉📋 Editor de consultas: cole e clique em Executar:

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

👀 Você vai encontrar quatro playlists:

pl.playlist_name

pl.followers

streams_reaching_this_playlist

músicas

Em alta agora

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

Na estrada

5.000.000

2.400.000.000

Neon Summer, Slow Arrow

Gym Pump

3.000.000

2.000.000.000

Neon Summer

Resultado da GQL: quatro playlists com o número de streams de cada uma

Leia a linha MATCH como uma frase: comece em um rótulo, volte para os artistas, para as músicas, para as entradas da playlist em que essas músicas estão e avance para as playlists. As setas apontam para a maneira como as bordas foram declaradas. <- anda para trás.

Agora some essa terceira coluna. 12,6 bilhões: o número que SUM informou na etapa quatro, que estava errado.

Aqui está a resposta certa. Naquela época, a questão era quanto a Cymbal transmitia, e uma música era contabilizada uma vez, não importa em quantas playlists ela estivesse. Essa pergunta é onde esses streams chegam, e uma música em quatro playlists realmente alcança quatro públicos-alvo. A duplicação GRAPH_EXPAND produz um erro para uma pergunta e a resposta para a outra. O AGG nunca foi sobre duplicatas serem ruins, mas sim sobre corresponder a aritmética à pergunta.

2. Retornar os próprios caminhos

Remova a agregação e peça as rotas.

👉📋 Editor de consultas: cole e clique em Executar:

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 = nomeia a correspondência inteira, e TO_JSON a renderiza.

👀 Expect 8 linhas, uma coluna path. Cada célula é uma matriz JSON dos nós e arestas ao longo de uma rota, e cada nó carrega seus labels e properties.

8 linhas, cada uma com um caminho JSON, com uma guia &quot;Gráfico&quot; no painel de resultados

Oito linhas para quatro músicas, porque existe uma rota por posição, não por música.

3. Abra a guia "Gráfico".

👉🌐 Console: acima dos resultados, clique em Gráfico.

Essa guia só aparece quando um resultado contém elementos de gráfico. A consulta anterior retornou números, então não tinha uma guia "Gráfico". Esta retorna caminhos, então tem.

a guia &quot;Gráfico&quot; mostrando o subgrafo da Cymbal em um layout de força

Você recebe o canto do gráfico do Cymbal desenhado como um layout de força, com uma contagem dos nós e bordas em exibição e um ícone por rótulo. Arraste um nó para separar o layout ou clique em um para ler as propriedades dele.

✅ Checkpoint:a terceira coluna da primeira consulta soma 12,6 bilhões, a segunda consulta retorna oito caminhos, e a guia "Gráfico" os mostra.

13. (OPCIONAL) Conversar com o gráfico

Não há SQL nesta etapa. Os agentes de dados do BigQuery podem usar um gráfico como fonte de conhecimento, e a documentação diz que eles usam medidas para agregação multinível. Vamos ver se isso é verdade.

1. Criar um agente

👉🌐 Console: no menu de navegação do BigQuery à esquerda, clique em Agentes, Catálogo de agentes e Criar agente.

👉🌐 Console: digite Music graph agent em Nome do agente e isto em Descrição do agente:

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

👉🌐 Console: em Fontes de conhecimento, clique em Adicionar fonte. Na caixa de diálogo Selecionar fontes, expanda seu projeto, music, Gráficos, marque MusicGraph e clique em Confirmar.

👀 O botão Adicionar fonte fica cinza. Um agente pode conter no máximo um gráfico e não pode misturar gráficos com tabelas.

a caixa de diálogo &quot;Selecionar fontes&quot; com a opção &quot;MusicGraph&quot; marcada e selecionada (1)

👉🌐 Console: deixe a Região como foi definida no local do gráfico. Clique em Salvar e em Publicar. No painel Canais de publicação, clique em Publicar agente e feche a confirmação.

2. Faça a pergunta

👉🌐 Console: clique em Criar conversa. Uma página de chat é aberta. Digite isso na caixa Fazer uma pergunta na parte de baixo e pressione Enter:

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

👀 O agente retorna uma tabela e um resumo de uma frase:

label_name

total_streams

playlist_placements

Cymbal Records

5.100.000.000

8

Northwind Audio

4.500.000.000

2

a resposta do agente: a tabela e o resumo de uma frase

5,1 bilhões. Ninguém falou sobre distribuição de dados para o agente, e ele não se enquadrou nisso.

3. Ler a consulta que ele escreveu

👉🌐 Console: no menu de navegação, clique em Explorador de jobs e no job mais recente. Os rótulos incluem ca-bq-job: true e data-agent-id com o ID do seu agente, e a consulta é:

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

Explorador de jobs: os rótulos do job (ca-bq-job, data-agent-id) e o SQL dele

Ele usou GRAPH_EXPAND e AGG por conta própria, porque as medidas estavam no esquema que ele leu. Nada na descrição do agente menciona você.

✅ Checkpoint:5, 1 bilhões na resposta do chat e AGG(...) no SQL do job.

14. Limpar

👉💻 Cloud Shell: solte o conjunto de dados, as tabelas e o gráfico de propriedades:

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

👀 Espere ✓ dropped YOUR_PROJECT_ID.music (tables and graph).

Se você criou o agente de dados opcional, exclua-o no console em Agentes → Catálogo de agentes. Se ./setup_project.sh criou um projeto apenas para este laboratório, a limpeza mais organizada de todas é encerrar todo o projeto. O ID está em ~/project_id.txt.

15. Parabéns

Você declarou uma linha, MEASURE(SUM(streams)), e ela mudou 12,6 bilhões para 5,1 bilhões, para você e para todas as consultas que alguém escrever nesse gráfico depois, incluindo as que um agente escrever.

O que você aprendeu

  • Uma métrica é um agregado declarado em um nó, ao lado da KEY que define o nível de detalhe dela.
  • GRAPH_EXPAND nivela o gráfico em uma tabela ampla com TableLabel_property colunas.
  • AGG é a única função que lê uma métrica, e o sistema de tipos a aplica de quatro maneiras diferentes.
  • Seis agregações estão disponíveis, e os resultados de AGG são valores comuns que podem ser divididos.
  • Mudar o GROUP BY faz com que a pergunta seja feita novamente sem afetar a métrica.
  • GRAPH_EXPAND quer uma raiz, arestas de muitos para um e junções promovidas a nós.

A tabela de decisão

Sintoma

Causa

Correção

Um total muito grande

SUM sobre uma coluna aberta

declarar uma métrica e lê-la com AGG

"expected MEASURE, found INT64"

AGG em uma coluna simples

use SUM ou declare a métrica

"Não é permitido retornar expressões do tipo MEASURE"

coluna de medida sem AGG

unir: AGG(...)

"não exposto pelo tipo de elemento"

Métrica referenciada no GQL

mede o atraso em relação a GRAPH_EXPAND

GRAPH_EXPAND ignora uma aresta ou falha

junção modelada como uma aresta

promover a tabela de junção a um nó

Um número antigo depois de mudar o gráfico

resultado em cache

desmarque Usar resultados em cache

O que não abordamos (de propósito)

Descrições e sinônimos em propriedades, consultas verificadas e glossários para agentes de dados, GQL além de um MATCH, medidas em mais de um gráfico. Cada um é um laboratório independente.

Saiba mais