Visão geral das consultas do gráfico do Spanner

Este documento descreve como consultar gráficos de propriedade no Spanner Graph. Os exemplos desta seção usam o esquema de gráfico criado em Configurar e consultar o Spanner Graph, ilustrado no diagrama a seguir:

Exemplo de esquema do Spanner Graph.

Executar uma consulta do gráfico do Spanner

É possível executar consultas de gráfico do Spanner das seguintes maneiras:

Estrutura de consulta do Spanner Graph

Esta seção descreve cada componente da consulta em detalhes.

O exemplo a seguir ilustra a estrutura básica de um gráfico do Spanner consulta.

Exemplo de estrutura de consulta do Spanner Graph.

Com o gráfico do Spanner, é possível criar vários gráficos dentro de 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. O mais básico Os padrões são padrões de elementos (padrões de nós e padrões de borda), que correspondem ao elementos (nós e bordas, respectivamente). Os padrões de elementos podem ser compostos 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 contém um par correspondente de parênteses, que podem opcionalmente 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 nó corresponde a todos os nós do 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 do gráfico que têm Person marcador. A consulta retorna as propriedades label, id e 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 do gráfico que têm o Marcador Person ou Account. O conjunto de propriedades expostas pelo a variável de padrão de gráfico n é o superconjunto das propriedades expostas pelo 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 propriedade create_time, mas não têm têm a propriedade birthday. Um NULL é retornado para a propriedade birthday. para esses nós.
  • Os nós que correspondem ao rótulo Person têm a propriedade birthday, mas não têm a propriedade create_time. Um NULL é retornado para o create_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 de 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 borda são entre colchetes [] com os símbolos -, -> ou <- para indicar direções

Semelhante aos padrões de nós, as variáveis de padrão de grafo são usadas para se vincular à borda correspondente os elementos.

Encontrar todas as bordas com rótulos correspondentes

A consulta a seguir retorna todas as arestas do gráfico que têm o rótulo Owns. A variável de padrão de gráfico e está vinculada às bordas 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 correspondam à expressão de rótulo e ao filtro de propriedade

Semelhante a um padrão de nó, um padrão de borda pode usar expressões de rótulo, especificação de propriedade e cláusulas WHERE, conforme mostrado consulta a seguir. 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 do gráfico do Spanner sejam direcionadas, é possível usar Padrão de aresta any direction -[]- em uma consulta para corresponder 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 a partir de padrões alternados de nó e borda.

Encontrar todos os caminhos de um nó com rótulos e filtros de propriedades especificados, usando um padrão de caminho

A consulta a seguir encontra todas as transferências para uma conta iniciadas em uma conta de propriedade de Person com id igual a 2.

Cada resultado correspondente representa um caminho de Person {id: 2} até um conectou Account usando a borda Owns a outra Account usando a Transfers borda.

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 group variable e. Para mais informações, consulte variável de grupo de acesso.

Algumas linhas nos resultados do exemplo são repetidas porque pode haver várias 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 Account nós com um a dois Transfers ultrapassa contas intermediárias bloqueadas.

O padrão de caminho entre parênteses é quantificado e a cláusula WHERE é usada na os parênteses para especificar as condições do 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

Agrupar variáveis

Uma variável de padrão de gráfico declarada em um padrão quantificado é considerada uma variável de grupo. quando acessado fora do padrão quantificado, e vinculado a uma matriz elementos gráficos 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.

Variável do grupo de acesso

No exemplo a seguir, a variável e é acessada da seguinte maneira:

  • Uma variável de padrão de gráfico vinculada a uma única borda 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ção RETURN (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 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 a mesma origem e nós de destino, é possível usar o prefixo de pesquisa do caminho ANY ou ANY SHORTEST. Você só pode aplicar esses prefixos antes de um padrão de caminho inteiro, e não é possível aplicá-los entre parênteses.

Corresponder usando QUALQUER

A consulta a seguir encontra todas as contas exclusivas acessíveis que são uma ou duas Transfers de distância 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 a seguir, embora seja possível alcançar o nó Account com {id: 16} em duas caminhos do nó Account de origem, os resultados incluirão 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 caminho produz uma coleção de caminhos.

Fazer a correspondência usando um padrão gráfico

A consulta a seguir identifica contas intermediárias e seus proprietários envolvidos em valores de transações superiores a 200, por meio dos quais os fundos são transferidos de uma conta de origem para uma conta bloqueada.

Os padrões de caminho a seguir 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 encontra caminhos de uma conta para a pessoa proprietária.

A variável interm atua como um vínculo comum entre os dois padrões de caminho, que requer que interm faça referência ao mesmo nó de elemento em ambos os 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. O entrada está vazia na 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 localiza a conta e o proprietário com a maior quantidade de 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 as declaraçõ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
src_account transferir dst_account
{id: 7} {amount: 300.0} {id: 16, is_blocked: true}
{id: 7} {amount: 100.0} {id: 16, is_blocked: true}
{id: 20} {amount: 200.0} {id: 16, is_blocked: true}

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

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

MATCH
  (src_account:Account)
    <-[owns:Owns]-
  (owner:Person)
src_account transferir dst_account possui proprietário
{id: 7} {amount: 300.0} {id: 16, is_blocked: true} {person_id: 1, account_id: 7} {id: 1, name: Alex}

RETURN
  src_account.id AS account_id,
  owner.name AS owner_name
account_id owner_name
7 Alex

Result

account_id owner_name
7 Alex

Instrução de retorno

A instrução de retorno define o que será retornado dos padrões correspondentes. Ele pode acessar graficamente variáveis de padrão e contêm expressões e outras cláusulas, como ORDER_BY, GROUP_BY. Consulte a instrução RETURN.

O Spanner Graph não oferece suporte para retornar 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"}}

Criar consultas maiores com a palavra-chave NEXT

É possível encadear várias instruções de consulta linear de gráfico usando o NEXT. palavra-chave. 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 mostra o proprietário da conta com mais mensagens recebidas encadeando várias instruções lineares do 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, operadores e condicionais no GoogleSQL, incluindo funções de agregação e outras funções escalares na consulta do Spanner Graph.

O Spanner Graph também oferece suporte a funções e operadores integrados para elementos de gráfico.

Funções e operadores integrados

As seguintes funções e operadores são comumente usados em GQL:

  • PROPERTY_EXISTS(n, birthday): retorna se n expõe a propriedade birthday.
  • LABELS(n): retorna os rótulos de n, conforme definido no esquema do gráfico.
  • PROPERTY_NAMES(n): retorna os nomes de propriedades de n.
  • TO_JSON(n): retorna n no formato JSON. Para mais informações, consulte a função TO_JSON.

A consulta a seguir ilustra o predicado PROPERTY_EXISTS, a função LABELS e TO_JSON, bem como 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 person
falso verdadeiro Pessoa ["Vacation Fund"] Adelaide, Austrália {&quot;identifier&quot;:&quot;mUZpbkdyYXBoLlBlcnNvbgB4kQI=&quot;,&quot;kind&quot;:&quot;node&quot;,&quot;labels&quot;:[&quot;Person&quot;],&quot;properties&quot;:{&quot;birthday&quot;:&quot;1991-12-21T08:00:00Z&quot;,&quot;city&quot;:&quot;Adelaide&quot;,&quot;country&quot;:&quot;Australia&quot;,&quot;id&quot;:1,&quot;name&quot;:&quot;Alex&quot;}}

Subconsultas

Uma subconsulta é uma consulta aninhada em outra. As listas a seguir Regras de subconsulta do gráfico do Spanner:

  • Uma subconsulta é encerrada 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 igual ao mostrado usada 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 é entre chaves {} com o prefixo VALUE pela palavra-chave. A consulta retorna o valor total o total de transferências iniciadas em 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 uma lista de expressões de subconsulta compatíveis, consulte Subconsultas do gráfico do Spanner.

Parâmetros de consulta

É possível consultar o gráfico do Spanner com parâmetros. Para mais informações, consulte a sintaxe e aprender a 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 com SQL para acessar informações de seus gráficos e tabelas juntos 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 de tabela que pode ser perfeitamente integrada a uma consulta SQL. Isso a interoperabilidade permite enriquecer os resultados das consultas gráficas com conteúdo que não é 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

Saiba mais sobre as práticas recomendadas para ajustar consultas.