Este documento descreve como consultar gráficos de propriedades no Spanner Graph. Os exemplos desta seção usam o esquema de gráfico criado em Configurar e consultar o Spanner Graph, que é ilustrado no diagrama a seguir:
Executar uma consulta do Spanner Graph
É possível executar consultas do Spanner Graph das seguintes maneiras:
O console do Google Cloud
Envie uma consulta na página do Spanner Studio. Para acessar a página Spanner Studio, clique em Spanner Studio na página Visão geral do banco de dados ou Visão geral da tabela. Para mais informações sobre como acessar o Spanner Studio, consulte Gerenciar seus dados usando o console do Google Cloud .
Ferramenta de linha de comando
gcloud spanner
Envie um comando usando o comando
gcloud spanner databases execute-sql
.As API REST
executeSql
eexecuteStreamingSql
As APIs
ExecuteSql
eExecuteStreamingSql
RPC
Estrutura de consulta do Spanner Graph
Esta seção descreve cada componente de consulta em detalhes.
O exemplo a seguir ilustra a estrutura básica de uma consulta de gráfico do Spanner.
O Spanner Graph permite criar vários gráficos em um banco de dados.
A consulta começa especificando o gráfico de destino, FinGraph
, usando
a cláusula GRAPH
.
Correspondência de padrões de gráfico
A correspondência de padrões de gráfico encontra padrões específicos no gráfico. Os padrões mais básicos são os de elementos (padrões de nó e de aresta), que correspondem aos elementos do gráfico (nós e arestas, respectivamente). Os padrões de elemento podem ser compostos em padrões de caminho e padrões mais complexos.
Padrões de nó
Um padrão de nó é um padrão que corresponde aos nós do seu gráfico. Esse padrão é composto por um par correspondente de parênteses, que pode conter uma variável de padrão de gráfico, uma expressão de rótulo e filtros de propriedade.
Encontrar todos os nós
A consulta a seguir retorna todos os nós no gráfico. A variável n
, chamada
de variável de padrão de gráfico, é vinculada aos nós correspondentes. Nesse caso, o padrão de nó
corresponde a todos os nós no gráfico.
GRAPH FinGraph
MATCH (n)
RETURN LABELS(n) AS label, n.id;
Result
A consulta retorna label
e id
da seguinte maneira:
o rótulo. | id |
---|---|
Conta | 7 |
Conta | 16 |
Conta | 20 |
Pessoa | 1 |
Pessoa | 2 |
Pessoa | 3 |
Encontrar todos os nós com um rótulo específico
A consulta a seguir corresponde a todos os nós no gráfico que têm o rótulo Person
.
A consulta retorna as propriedades label
e id
, name
dos nós correspondentes.
GRAPH FinGraph
MATCH (p:Person)
RETURN LABELS(p) AS label, p.id, p.name;
Result
o rótulo. | id | name |
---|---|---|
Pessoa | 1 | Alex |
Pessoa | 2 | Dana |
Pessoa | 3 | Lee |
Encontrar todos os nós que correspondem a uma expressão de rótulo
É possível criar uma expressão de rótulo com um ou mais operadores lógicos.
A consulta a seguir corresponde a todos os nós no gráfico que têm o rótulo
Person
ou Account
. O conjunto de propriedades exposto pela
variável de padrão de gráfico n
é o superconjunto das propriedades expostas pelos
nós que têm o rótulo Person
ou Account
.
GRAPH FinGraph
MATCH (n:Person|Account)
RETURN LABELS(n) AS label, n.id, n.birthday, n.create_time;
- Nos resultados, todos os nós têm a propriedade
id
. - Os nós que correspondem ao rótulo
Account
têm a propriedadecreate_time
, mas não têm a propriedadebirthday
. UmNULL
é retornado para a propriedadebirthday
para esses nós. - Os nós que correspondem ao rótulo
Person
têm a propriedadebirthday
, mas não têm a propriedadecreate_time
. UmNULL
é retornado para a propriedadecreate_time
para esses nós.
Result
o rótulo. | id | Data de nascimento | create_time |
---|---|---|---|
Conta | 7 | NULL | 2020-01-10T14:22:20.222Z |
Conta | 16 | NULL | 2020-01-28T01:55:09.206Z |
Conta | 20 | NULL | 2020-02-18T13:44:20.655Z |
Pessoa | 1 | 1991-12-21T08:00:00Z | NULL |
Pessoa | 2 | 1980-10-31T08:00:00Z | NULL |
Pessoa | 3 | 1986-12-07T08:00:00Z | NULL |
Para mais informações sobre as regras de expressão de rótulos, consulte Expressão de rótulos.
Encontrar todos os nós que correspondem à expressão do rótulo e ao filtro de propriedade
A consulta a seguir corresponde a todos os nós no gráfico que têm o rótulo Person
e em que a propriedade id
é igual a 1
.
GRAPH FinGraph
MATCH (p:Person {id: 1})
RETURN LABELS(p) AS label, p.id, p.name, p.birthday;
Result
o rótulo. | id | name | Data de nascimento |
---|---|---|---|
Pessoa | 1 | Alex | 1991-12-21T08:00:00Z |
É possível usar a cláusula WHERE
para formar condições de filtragem mais complexas em
rótulos e propriedades.
A consulta a seguir corresponde a todos os nós no gráfico que têm o rótulo Person
, e a propriedade birthday
está antes de 1990-01-10
.
GRAPH FinGraph
MATCH (p:Person WHERE p.birthday < '1990-01-10')
RETURN LABELS(p) AS label, p.name, p.birthday;
Result
o rótulo. | name | Data de nascimento |
---|---|---|
Pessoa | Dana | 1980-10-31T08:00:00Z |
Pessoa | Lee | 1986-12-07T08:00:00Z |
Padrões de borda
Um padrão de aresta corresponde a arestas ou relações entre nós. Os padrões de aresta são
enquadrados com colchetes []
com símbolos -
, ->
ou <-
para indicar
direções.
Assim como os padrões de nó, as variáveis de padrão de gráfico são usadas para vincular elementos de aresta correspondentes.
Encontrar todas as arestas com rótulos correspondentes
A consulta a seguir retorna todas as arestas no gráfico que têm o rótulo Owns
.
A variável de padrão de gráfico e
está vinculada às arestas correspondentes.
GRAPH FinGraph
MATCH -[e:Owns]->
RETURN e.id AS owner_id, e.account_id;
Result
owner_id | account_id |
---|---|
1 | 7 |
3 | 16 |
2 | 20 |
Encontrar todas as arestas que correspondem à expressão do rótulo e ao filtro de propriedade
Assim como um padrão de nó, um padrão de aresta pode usar
expressões de rótulo, especificação de propriedade e cláusulas WHERE
, conforme mostrado na
consulta abaixo. A consulta encontra todas as arestas marcadas com Owns
e tem a
propriedade create_time
em um período especificado.
GRAPH FinGraph
MATCH -[e:Owns WHERE e.create_time > '2020-01-14'
AND e.create_time < '2020-05-14']->
RETURN e.id AS owner_id, e.create_time, e.account_id;
Result
owner_id | create_time | account_id |
---|---|---|
2 | 2020-01-28T01:55:09.206Z | 20 |
3 | 2020-02-18T13:44:20.655Z | 16 |
Encontrar todas as arestas usando qualquer padrão de direção
Embora todas as arestas no Spanner Graph sejam direcionadas, é possível usar o
padrão de aresta any direction
-[]-
em uma consulta para corresponder a arestas em qualquer direção.
A consulta a seguir encontra todas as transferências em que uma conta bloqueada está envolvida.
GRAPH FinGraph
MATCH (account:Account)-[transfer:Transfers]-(:Account)
WHERE account.is_blocked
RETURN transfer.order_number, transfer.amount;
Result
order_number | amount |
---|---|
304330008004315 | 300 |
304120005529714 | 100 |
103650009791820 | 300 |
302290001255747 | 200 |
Padrões de caminho
Um padrão de caminho é criado com padrões de nó e de aresta alternados.
Encontrar todos os caminhos de um nó com filtros de rótulo e propriedade especificados usando um padrão de caminho
A consulta a seguir encontra todas as transferências para uma conta iniciada de uma conta
pertencente a Person
com id
igual a 2
.
Cada resultado correspondente representa um caminho de Person
{id: 2}
por uma
Account
conectada usando a borda Owns
para outra Account
usando a
borda Transfers
.
GRAPH FinGraph
MATCH
(p:Person {id: 2})-[:Owns]->(account:Account)-[t:Transfers]->
(to_account:Account)
RETURN
p.id AS sender_id, account.id AS from_id, to_account.id AS to_id;
Result
sender_id | from_id | to_id |
---|---|---|
2 | 20 | 7 |
2 | 20 | 16 |
Padrões de caminho quantificados
Um padrão quantificado permite que um padrão seja repetido em um intervalo especificado.
Corresponder a um padrão de aresta quantificado
A consulta a seguir encontra todas as contas de destino de uma a três
transferências de uma Account
de origem com id
igual a 7
, exceto
ela mesma.
O padrão de borda com o sufixo {1, 3}
.
GRAPH FinGraph
MATCH (src:Account {id: 7})-[e:Transfers]->{1, 3}(dst:Account)
WHERE src != dst
RETURN src.id AS src_account_id, ARRAY_LENGTH(e) AS path_length, dst.id AS dst_account_id;
Result
src_account_id | path_length | dst_account_id |
---|---|---|
7 | 1 | 16 |
7 | 1 | 16 |
7 | 1 | 16 |
7 | 3 | 16 |
7 | 3 | 16 |
7 | 2 | 20 |
7 | 2 | 20 |
O exemplo anterior usa a função ARRAY_LENGTH
para acessar o
e
group variable
. Para
mais informações, consulte Variável de grupo de acesso.
Algumas linhas nos resultados do exemplo são repetidas porque pode haver vários
caminhos entre o mesmo par de contas src
e dst
que correspondem ao padrão.
Corresponder a um padrão de caminho quantificado
A consulta a seguir encontra caminhos entre nós Account
com uma a duas
arestas Transfers
por contas intermediárias bloqueadas.
O padrão de caminho entre parênteses é quantificado, e a cláusula WHERE
é usada nos
parênteses para especificar condições para o padrão repetido.
GRAPH FinGraph
MATCH
(src:Account)
((:Account)-[:Transfers]->(interm:Account) WHERE interm.is_blocked){1,2}
-[:Transfers]->(dst:Account)
RETURN src.id AS src_account_id, dst.id AS dst_account_id;
Result
src_account_id | dst_account_id |
---|---|
7 | 20 |
7 | 20 |
20 | 20 |
Variáveis de grupo
Uma variável de padrão de gráfico declarada em um padrão quantificado é considerada uma variável de grupo quando acessada fora do padrão quantificado e é vinculada a uma matriz de elementos de gráfico correspondentes.
É possível acessar uma variável de grupo como uma matriz em que os elementos do gráfico são preservados na ordem de aparição ao longo dos caminhos correspondentes. É possível agregar uma variável de grupo usando a agregação horizontal.
Acessar variável de grupo
No exemplo abaixo, a variável e
é acessada da seguinte maneira:
- Uma variável de padrão de gráfico vinculada a uma única aresta na cláusula
WHERE
e.amount > 100
(dentro do padrão quantificado). - Uma variável de grupo vinculada a uma matriz de elementos de borda em
ARRAY_LENGTH(e)
na instruçãoRETURN
(fora do padrão quantificado). - Uma variável de grupo vinculada a uma matriz de elementos de borda, que é agregada
por
SUM(e.amount)
fora do padrão quantificado. Este é um exemplo de agregação horizontal.
GRAPH FinGraph
MATCH
(src:Account {id: 7})-[e:Transfers WHERE e.amount > 100]->{0,2}
(dst:Account)
WHERE src.id != dst.id
LET total_amount = SUM(e.amount)
RETURN
src.id AS src_account_id, ARRAY_LENGTH(e) AS path_length,
total_amount, dst.id AS dst_account_id;
Result
src_account_id | path_length | total_amount | dst_account_id |
---|---|---|---|
7 | 1 | 300 | 16 |
7 | 2 | 600 | 20 |
Qualquer caminho mais curto
Para limitar os caminhos correspondentes em cada grupo de caminhos que compartilham os mesmos nós de origem e
destino, use o prefixo de pesquisa do caminho ANY
ou ANY SHORTEST
.
Esses prefixos só podem ser aplicados antes de um padrão de caminho inteiro,
e não podem ser usados entre parênteses.
Corresponder usando QUALQUER
A consulta a seguir encontra todas as contas únicas acessíveis que estão a uma ou duas
Transfers
de um determinado nó Account
.
O prefixo de pesquisa de caminho ANY
garante que apenas um caminho entre um par
exclusivo de nós src
e dst
Account
seja retornado. No exemplo abaixo,
embora seja possível acessar o nó Account
com {id: 16}
em dois caminhos
diferentes do nó de origem Account
, os resultados incluem apenas um caminho.
GRAPH FinGraph
MATCH ANY (src:Account {id: 7})-[e:Transfers]->{1,2}(dst:Account)
LET ids_in_path = ARRAY(SELECT e.to_id FROM UNNEST(e) AS e)
RETURN src.id AS src_account_id, dst.id AS dst_account_id, ids_in_path;
Result
src_account_id | dst_account_id | ids_in_path |
---|---|---|
7 | 16 | 16 |
7 | 20 | 16,20 |
Padrões de gráfico
Um padrão de gráfico consiste em um ou mais padrões de caminho, separados por vírgula ,
.
Os padrões de gráfico podem conter uma cláusula WHERE
, que permite acessar todas as variáveis de padrão de gráfico nos padrões de caminho para formar condições de filtragem. Cada padrão de caminho
produz uma coleção de caminhos.
Fazer correspondência usando um padrão de gráfico
A consulta a seguir identifica as contas intermediárias e os proprietários delas envolvidos em transações com valores acima de 200, em que os fundos são transferidos de uma conta de origem para uma conta bloqueada.
Os seguintes padrões de caminho formam o padrão de gráfico:
- O primeiro padrão encontra caminhos em que a transferência ocorre de uma conta para uma conta bloqueada usando uma conta intermediária.
- O segundo padrão encontra caminhos de uma conta para a pessoa proprietária.
A variável interm
atua como um link comum entre os dois padrões de caminho, o que
requer que interm
faça referência ao mesmo nó de elemento nos dois padrões de caminho. Isso
cria uma operação de união igual com base na variável interm
.
GRAPH FinGraph
MATCH
(src:Account)-[t1:Transfers]->(interm:Account)-[t2:Transfers]->(dst:Account),
(interm)<-[:Owns]-(p:Person)
WHERE dst.is_blocked = TRUE AND t1.amount > 200 AND t2.amount > 200
RETURN
src.id AS src_account_id, dst.id AS dst_account_id,
interm.id AS interm_account_id, p.id AS owner_id;
Result
src_account_id | dst_account_id | interm_account_id | owner_id |
---|---|---|---|
20 | 16 | 7 | 1 |
Instruções de consulta linear
É possível encadear várias instruções de gráfico para formar uma instrução de consulta linear. As instruções são executadas na mesma ordem em que aparecem na consulta.
- Cada instrução usa a saída da instrução anterior como entrada. A entrada está vazia para a primeira instrução.
- A saída da última instrução é o resultado final.
Encontrar a transferência máxima para uma conta bloqueada
A consulta a seguir encontra a conta e o proprietário com a maior transferência para uma conta bloqueada.
GRAPH FinGraph
MATCH (src_account:Account)-[transfer:Transfers]->(dst_account:Account)
WHERE dst_account.is_blocked
ORDER BY transfer.amount DESC
LIMIT 1
MATCH (src_account:Account)<-[owns:Owns]-(owner:Person)
RETURN src_account.id AS account_id, owner.name AS owner_name;
A tabela a seguir ilustra como os resultados intermediários são transmitidos para as instruções. Para fins de concisão, apenas algumas propriedades dos resultados intermediários são mostradas.
Instrução | Resultado intermediário (abreviado) | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
MATCH (src_account:Account) -[transfer:Transfers]-> (dst_account:Account) WHERE dst_account.is_blocked |
|
||||||||||||
ORDER BY transfer.amount DESC |
|
||||||||||||
LIMIT 1 |
|
||||||||||||
MATCH (src_account:Account) <-[owns:Owns]- (owner:Person) |
|
||||||||||||
RETURN src_account.id AS account_id, owner.name AS owner_name |
|
Result
account_id | owner_name |
---|---|
7 | Alex |
Instrução de retorno
A instrução de retorno define o que retornar dos padrões correspondentes. Ele pode acessar
variáveis de padrão de gráfico, conter expressões e outras cláusulas, como ORDER_BY,
GROUP_BY. Consulte a instrução RETURN
.
O Spanner Graph não oferece suporte ao retorno de elementos de gráfico como resultados de consulta. Para retornar o elemento de gráfico inteiro, use a função TO_JSON
.
Retornar elementos do gráfico como JSON
GRAPH FinGraph
MATCH (n:Account {id: 7})
-- Returning a graph element in the final results is NOT allowed. Instead, use
-- the TO_JSON function or explicitly return the graph element's properties.
RETURN TO_JSON(n) AS n;
Result
n |
---|
{"identifier":"mUZpbkdyYXBoLkFjY291bnQAeJEO","kind":"node","labels":["Account"],"properties":{"create_time":"2020-01-10T14:22:20.222Z","id":7,"is_blocked":false,"nick_name":"Vacation Fund"}} |
Como criar consultas maiores com a palavra-chave NEXT
É possível encadear várias instruções de consulta linear de gráfico usando a palavra-chave NEXT
. A entrada para a primeira instrução de consulta linear está vazia. A saída de cada
instrução de consulta linear se torna a entrada da próxima instrução de consulta linear.
O exemplo a seguir encontra o proprietário da conta com a maioria das transferências
de entrada, encadeando várias instruções lineares de gráfico. É possível
usar a mesma variável, account
neste exemplo, para se referir ao mesmo elemento
do gráfico em várias instruções lineares.
GRAPH FinGraph
MATCH (:Account)-[:Transfers]->(account:Account)
RETURN account, COUNT(*) AS num_incoming_transfers
GROUP BY account
ORDER BY num_incoming_transfers DESC
LIMIT 1
NEXT
MATCH (account:Account)<-[:Owns]-(owner:Person)
RETURN account.id AS account_id, owner.name AS owner_name, num_incoming_transfers;
Result
account_id | owner_name | num_incoming_transfers |
---|---|---|
16 | Lee | 3 |
Funções e expressões
É possível usar todas as funções (funções agregadas e escalares), operadores e expressões condicionais do GoogleSQL na consulta do Spanner Graph. O Spanner Graph também oferece suporte a funções e operadores específicos do gráfico.
Funções e operadores integrados
As seguintes funções e operadores são comumente usados no GQL:
PROPERTY_EXISTS(n, birthday)
: retorna sen
expõe a propriedadebirthday
.LABELS(n)
: retorna os rótulos den
, conforme definido no esquema do gráfico.PROPERTY_NAMES(n)
: retorna os nomes de propriedade den
.TO_JSON(n)
: retornan
no formato JSON. Para mais informações, consulte a funçãoTO_JSON
.
A consulta a seguir ilustra o predicado PROPERTY_EXISTS
,a função LABELS
e a função TO_JSON
, além de outras funções integradas, como ARRAY_AGG
e CONCAT
.
GRAPH FinGraph
MATCH (person:Person)-[:Owns]->(account:Account)
RETURN person, ARRAY_AGG(account.nick_name) AS accounts
GROUP BY person
NEXT
RETURN
LABELS(person) AS labels,
TO_JSON(person) AS person,
accounts,
CONCAT(person.city, ", ", person.country) AS location,
PROPERTY_EXISTS(person, is_blocked) AS is_blocked_property_exists,
PROPERTY_EXISTS(person, name) AS name_property_exists
LIMIT 1;
Result
is_blocked_property_exists | name_property_exists | rótulos | contas | local | pessoa |
---|---|---|---|---|---|
falso | verdadeiro | Pessoa | ["Vacation Fund"] | Adelaide, Austrália | {"identifier":"mUZpbkdyYXBoLlBlcnNvbgB4kQI=","kind":"node","labels":["Person"],"properties":{"birthday":"1991-12-21T08:00:00Z","city":"Adelaide","country":"Australia","id":1,"name":"Alex"}} |
Subconsultas
Uma subconsulta é uma consulta aninhada em outra. Confira a seguir as regras de subconsulta do Spanner Graph:
- Uma subconsulta é incluída entre chaves
{}
. - Uma subconsulta pode começar com a cláusula
GRAPH
principal para especificar o gráfico no escopo. O gráfico especificado não precisa ser o mesmo usado na consulta externa. - Quando a cláusula
GRAPH
é omitida na subconsulta, o seguinte ocorre:- O gráfico no escopo é inferido do contexto de consulta externa mais próximo.
- A subconsulta precisa começar com uma instrução de correspondência de padrão de gráfico
com o
MATCH.
- Uma variável de padrão de gráfico declarada fora do escopo da subconsulta não pode ser declarada novamente dentro da subconsulta, mas pode ser referenciada em expressões ou funções dentro da subconsulta.
Use uma subconsulta para encontrar o número total de transferências de cada conta
A consulta a seguir ilustra o uso da subconsulta VALUE
. A subconsulta é
incluída entre chaves {}
com o prefixo da palavra-chave VALUE
. A consulta retorna o valor total das transferências iniciadas de uma conta.
GRAPH FinGraph
MATCH (p:Person)-[:Owns]->(account:Account)
RETURN p.name, account.id AS account_id, VALUE {
MATCH (a:Account)-[transfer:Transfers]->(:Account)
WHERE a = account
RETURN SUM(transfer.amount) AS total_transfer
} AS total_transfer;
Result
name | account_id | total_transfer |
---|---|---|
Alex | 7 | 400 |
Dana | 20 | 700 |
Lee | 16 | 300 |
Para conferir uma lista de expressões de subconsultas com suporte, consulte Subconsultas do Spanner Graph.
Parâmetros de consulta
É possível consultar o Spanner Graph com parâmetros. Para mais informações, consulte a sintaxe e saiba como consultar dados com parâmetros nas bibliotecas de cliente do Spanner.
A consulta a seguir ilustra o uso dos parâmetros de consulta.
GRAPH FinGraph
MATCH (person:Person {id: @id})
RETURN person.name;
Consultar gráficos e tabelas juntos
É possível usar consultas de gráfico em conjunto com SQL para acessar informações de gráficos e tabelas em uma única instrução.
GRAPH_TABLE
O operador GRAPH_TABLE
usa uma consulta de gráfico linear e retorna o resultado em uma forma tabular que pode ser integrada perfeitamente a uma consulta SQL. Essa
interoperabilidade permite que você aprimore os resultados de consulta de gráfico com conteúdo que não é de gráfico e
vice-versa.
Por exemplo, é possível criar uma tabela CreditReports
e inserir alguns relatórios
de crédito, conforme mostrado no exemplo abaixo:
CREATE TABLE CreditReports (
person_id INT64 NOT NULL,
create_time TIMESTAMP NOT NULL,
score INT64 NOT NULL,
) PRIMARY KEY (person_id, create_time);
INSERT INTO CreditReports (person_id, create_time, score)
VALUES
(1,"2020-01-10 06:22:20.222", 700),
(2,"2020-02-10 06:22:20.222", 800),
(3,"2020-03-10 06:22:20.222", 750);
Em seguida, identifique pessoas de interesse pela correspondência de padrões de gráfico em GRAPH_TABLE
e mescle os resultados da consulta de gráfico com a tabela CreditReports
para acessar a pontuação
de crédito.
SELECT
gt.person.id,
credit.score AS latest_credit_score
FROM GRAPH_TABLE(
FinGraph
MATCH (person:Person)-[:Owns]->(:Account)-[:Transfers]->(account:Account)
WHERE account.is_blocked
RETURN DISTINCT person
) AS gt
JOIN CreditReports AS credit
ON gt.person.id = credit.person_id
ORDER BY credit.create_time;
Resultado:
person_id | latest_credit_score |
---|---|
1 | 700 |
2 | 800 |
A seguir
Conheça as práticas recomendadas para ajustar consultas.