Descripción general de las consultas de Spanner Graph

En este documento, se describe cómo consultar gráficos de propiedades en Spanner Graph. Los ejemplos de esta sección usan el esquema de gráfico que creaste en Configura y consulta Spanner Graph, que se ilustra en el siguiente diagrama:

Ejemplo de esquema del grafo de Spanner.

Ejecuta una consulta de grafo de Spanner

Puedes ejecutar consultas de grafo de Spanner de las siguientes maneras:

Estructura de la consulta de Spanner Graph

En esta sección, se describe cada componente de la consulta en detalle.

En el siguiente ejemplo, se ilustra la estructura básica de un grafo de Spanner para cada búsqueda.

Ejemplo de estructura de consulta de Spanner Graph.

Spanner Graph te permite crear varios grafos dentro de una base de datos. La consulta comienza por especificar el grafo de destino, FinGraph, con la cláusula GRAPH.

Coincidencia de patrones de grafos

La coincidencia de patrones en los gráficos encuentra patrones específicos en tu gráfico. La forma más básica son patrones del elemento (patrones de nodo y de borde), que coinciden con el gráfico (nodos y aristas, respectivamente). Los patrones de elementos se pueden componer patrones de ruta de acceso y patrones más complejos.

Patrones de nodos

Un patrón de nodo es un patrón que coincide con los nodos de tu gráfico. Este patrón comprende un par de paréntesis coincidente, que opcionalmente podría contienen una variable de patrón de gráfico, una expresión de etiqueta y filtros de propiedades.

Buscar todos los nodos

La siguiente consulta muestra todos los nodos del gráfico. La variable n, llamada variable de patrón de gráfico, se vincula a los nodos coincidentes. En este caso, el patrón de nodos coincide con todos los nodos del gráfico.

GRAPH FinGraph
MATCH (n)
RETURN LABELS(n) AS label, n.id;

Resultado

La consulta muestra label y id de la siguiente manera:

etiqueta id
Cuenta 7
Cuenta 16
Cuenta 20
Persona 1
Persona 2
Persona 3

Buscar todos los nodos con una etiqueta específica

La siguiente consulta coincide con todos los nodos del grafo que tienen la etiqueta Person. La consulta muestra las propiedades label, id y name de los nodos coincidentes.

GRAPH FinGraph
MATCH (p:Person)
RETURN LABELS(p) AS label, p.id, p.name;

Resultado

etiqueta id name
Persona 1 Alex
Persona 2 Dana
Persona 3 Lee

Busca todos los nodos que coincidan con una expresión de etiqueta

Puedes crear una expresión de etiqueta con uno o más operadores lógicos.

La siguiente consulta hace coincidir todos los nodos del gráfico que tienen Etiqueta Person o Account. El conjunto de propiedades que expone la variable de patrón de grafo n es el superconjunto de propiedades expuestas por el nodos que tienen la etiqueta Person o Account.

GRAPH FinGraph
MATCH (n:Person|Account)
RETURN LABELS(n) AS label, n.id, n.birthday, n.create_time;
  • En los resultados, todos los nodos tienen la propiedad id.
  • Los nodos que coinciden con la etiqueta Account tienen la propiedad create_time, pero no tienen la propiedad birthday. Se muestra un NULL para la propiedad birthday de esos nodos.
  • Los nodos que coinciden con la etiqueta Person tienen la propiedad birthday, pero no la tienen tienen la propiedad create_time. Se muestra un NULL para la propiedad create_time de esos nodos.

Resultado

etiqueta id cumpleaños create_time
Cuenta 7 NULL 2020-01-10T14:22:20.222Z
Cuenta 16 NULL 2020-01-28T01:55:09.206Z
Cuenta 20 NULL 2020-02-18T13:44:20.655Z
Persona 1 1991-12-21T08:00:00Z NULL
Persona 2 1980-10-31T08:00:00Z NULL
Persona 3 1986-12-07T08:00:00Z NULL

Para obtener más información sobre las reglas de expresión de etiquetas, consulta Expresión de etiqueta.

Buscar todos los nodos que coincidan con la expresión de la etiqueta y el filtro de propiedad

La siguiente consulta hace coincidir todos los nodos del gráfico que tienen la etiqueta Person. y donde la propiedad id es igual a 1.

GRAPH FinGraph
MATCH (p:Person {id: 1})
RETURN LABELS(p) AS label, p.id, p.name, p.birthday;

Resultado

etiqueta id name cumpleaños
Persona 1 Alex 1991-12-21T08:00:00Z

Puedes usar la cláusula WHERE para crear condiciones de filtrado más complejas en las etiquetas y las propiedades.

La siguiente consulta coincide con todos los nodos del gráfico que tienen Person. etiqueta y la propiedad birthday es anterior a 1990-01-10.

GRAPH FinGraph
MATCH (p:Person WHERE p.birthday < '1990-01-10')
RETURN LABELS(p) AS label, p.name, p.birthday;

Resultado

etiqueta name cumpleaños
Persona Dana 1980-10-31T08:00:00Z
Persona Lee 1986-12-07T08:00:00Z

Patrones de bordes

Un patrón de aristas coincide con bordes o relaciones entre nodos. Los patrones de borde son encerrado entre corchetes [] con los símbolos -, -> o <- para indicar cómo llegar a un lugar.

Al igual que los patrones de nodos, las variables de patrones de gráfico se usan para vincularse a elementos de borde que coincidan.

Busca todos los bordes con etiquetas coincidentes

Con la siguiente consulta, se muestran todas las aristas del gráfico que tienen la etiqueta Owns. La variable de patrón de gráfico e está vinculada a los bordes coincidentes.

GRAPH FinGraph
MATCH -[e:Owns]->
RETURN e.id AS owner_id, e.account_id;

Resultado

owner_id account_id
1 7
3 16
2 20

Buscar todas las aristas que coincidan con la expresión de la etiqueta y el filtro de propiedad

Al igual que un patrón de nodo, un patrón de borde puede usar etiquetas de recurso, especificación de propiedad y cláusulas WHERE, como se muestra en el siguiente consulta. La consulta encuentra todas las aristas etiquetadas con Owns y tiene la propiedad create_time en un 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;

Resultado

owner_id create_time account_id
2 2020-01-28T01:55:09.206Z 20
3 2020-02-18T13:44:20.655Z 16

Buscar todas las aristas con un patrón de bordes en dirección

Aunque todos los perímetros en el grafo de Spanner están dirigidos, puedes usar el El patrón de borde any direction -[]- en una consulta para que coincida con los bordes en cualquier dirección.

La siguiente consulta encuentra todas las transferencias en las que está involucrada una cuenta bloqueada.

GRAPH FinGraph
MATCH (account:Account)-[transfer:Transfers]-(:Account)
WHERE account.is_blocked
RETURN transfer.order_number, transfer.amount;

Resultado

order_number cantidad
304330008004315 300
304120005529714 100
103650009791820 300
302290001255747 200

Patrones de ruta de acceso

Los patrones de ruta se crean a partir de patrones de nodos y perímetros alternativos.

Encuentra todas las rutas de acceso de un nodo con filtros de etiquetas y propiedades especificados, mediante un patrón de ruta de acceso

La siguiente consulta busca todas las transferencias a una cuenta que se iniciaron desde una cuenta propiedad de Person con un id igual a 2.

Cada resultado coincidente representa una ruta de Person {id: 2} a través de un Account conectado con el perímetro Owns, en otro Account con el Borde de 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;

Resultado

sender_id from_id to_id
2 20 7
2 20 16

Patrones de ruta de acceso cuantificados

Un patrón cuantificado permite que un patrón se repita dentro de un rango especificado.

Hacer coincidir con un patrón de aristas cuantificado

La siguiente consulta encuentra todas las cuentas de destino entre una y tres transfieras desde una Account de origen con un id igual a 7, excepto a sí mismo.

El patrón de borde con el sufijo del cuantificador {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;

Resultado

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

En el ejemplo anterior, se usa la función ARRAY_LENGTH para acceder a la group variable e. Para Para obtener más información, consulta variable del grupo de acceso.

Algunas filas en los resultados del ejemplo están repetidas porque puede haber varias Rutas de acceso entre el mismo par de cuentas src y dst que coinciden con el patrón.

Coincidir con un patrón de ruta cuantificado

La siguiente consulta encuentra rutas entre Account nodos con uno a dos Se bloquearon Transfers de cuentas intermedias.

El patrón de ruta de acceso entre paréntesis se cuantifica y se usa la cláusula WHERE en paréntesis para especificar las condiciones del patrón 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;

Resultado

src_account_id dst_account_id
7 20
7 20
20 20

Cómo agrupar variables

Una variable de patrón de gráfico declarada en un patrón cuantificado se considera una variable de grupo cuando se accede a ella fuera del patrón cuantificado y se vincula a un array de elementos de gráfico coincidentes.

Puedes acceder a una variable de grupo como un array en el que se conservan los elementos del gráfico en el orden de aparición a lo largo de las rutas coincidentes. Puedes agregar un grupo variable usando la agregación horizontal.

Variable del grupo de acceso

En el siguiente ejemplo, se accede a la variable e de la siguiente manera:

  • Una variable de patrón de grafo vinculada a un solo borde en la cláusula WHERE e.amount > 100 (dentro del patrón cuantificado).
  • Una variable de grupo vinculada a un array de elementos perimetrales en ARRAY_LENGTH(e) en la sentencia RETURN (fuera del patrón cuantificado)
  • Una variable de grupo vinculada a un array de elementos perimetrales, que se agrega por SUM(e.amount) fuera del patrón cuantificado. Este es un ejemplo de agregación 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;

Resultado

src_account_id path_length total_amount dst_account_id
7 1 300 16
7 2 600 20

Cualquier ruta y cualquier ruta más corta

Para limitar las rutas coincidentes en cada grupo de rutas que comparten los mismos nodos de origen y destino, puedes usar el prefijo de búsqueda de la ruta ANY o ANY SHORTEST. Solo puedes aplicar estos prefijos antes de un patrón de ruta completo y no puedes aplicarlos dentro de paréntesis.

Cómo hacer coincidencias con CUALQUIERA

La siguiente consulta encuentra todas las cuentas únicas a las que se puede acceder, que son una o dos A Transfers de un nodo Account determinado.

El prefijo de búsqueda de ruta ANY garantiza que solo una ruta entre un se muestra el par de nodos Account de src y dst. En el siguiente ejemplo, aunque puedes llegar al nodo Account con {id: 16} en dos rutas diferentes desde el nodo Account de origen, los resultados solo incluyen una ruta.

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;

Resultado

src_account_id dst_account_id ids_in_path
7 16 16
7 20 16,20

Patrones de gráficos

Un patrón de gráfico consta de uno o más patrones de ruta de acceso, separados por comas ,. Los patrones gráficos pueden contener una cláusula WHERE, que te permite acceder a todos los las variables de patrón de grafos en los patrones de la ruta de acceso para formar condiciones de filtrado. Cada ruta produce una colección de rutas.

Hacer coincidir con un patrón de gráfico

La siguiente consulta identifica las cuentas intermediarias y sus propietarios involucrados en transacciones por un importe superior a 200, a través de las cuales se transfieren fondos de una cuenta de origen a una cuenta bloqueada.

Los siguientes patrones de ruta de acceso forman el patrón de grafo:

  • El primer patrón busca rutas en las que ocurre la transferencia desde una a una cuenta bloqueada que utiliza una cuenta intermedia.
  • El segundo patrón encuentra rutas de acceso de una cuenta a la persona propietaria.

La variable interm actúa como un vínculo común entre los dos patrones de ruta, lo que requiere que interm haga referencia al mismo nodo de elemento en ambos patrones de ruta. Esta Crea una operación de unión equivalente basada en la variable 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;

Resultado

src_account_id dst_account_id interm_account_id owner_id
20 16 7 1

Sentencias de consulta lineal

Puedes encadenar múltiples instrucciones de grafos para formar una instrucción de consulta lineal. Las instrucciones se ejecutan en el mismo orden en que aparecen en la consulta.

  • Cada instrucción toma el resultado de la instrucción anterior como entrada. El de entrada está vacía para la primera sentencia.
  • El resultado de la última declaración es el resultado final.

Encuentra la transferencia máxima a una cuenta bloqueada

La siguiente consulta encuentra la cuenta y su propietario con la mayor cantidad de solicitudes salientes transferir a una cuenta 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;

En la siguiente tabla, se ilustra cómo se pasan los resultados intermedios las declaraciones. Por brevedad, solo se muestran algunas propiedades de los resultados intermedios.

Declaración Resultado intermedio (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 es propietario de owner
{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

Resultado

account_id owner_name
7 Alex

Sentencia return

La sentencia Return define qué mostrar de los patrones coincidentes. Puede acceder a las variables de patrones de gráfico, contener expresiones y otras cláusulas, como ORDER_BY y GROUP_BY. Consulta la declaración RETURN.

Ten en cuenta que el gráfico de Spanner no admite la devolución de elementos del grafo como consulta. resultados. Para mostrar todo el elemento del gráfico, usa la función TO_JSON.

Muestra los elementos del 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;

Resultado

n
{&quot;identifier&quot;:&quot;mUZpbkdyYXBoLkFjY291bnQAeJEO&quot;,&quot;kind&quot;:&quot;node&quot;,&quot;labels&quot;:[&quot;Account&quot;],&quot;properties&quot;:{&quot;create_time&quot;:&quot;2020-01-10T14:22:20.222Z&quot;,&quot;id&quot;:7,&quot;is_blocked&quot;:false,&quot;nick_name&quot;:&quot;Vacation Fondo"}}

Cómo redactar consultas más grandes con la palabra clave NEXT

Puedes encadenar varias sentencias de consulta lineal de gráfico con la palabra clave NEXT. La entrada a la primera sentencia de consulta lineal está vacía. El resultado de cada la instrucción de consulta lineal se convierte en entrada para la siguiente instrucción de consulta lineal.

En el siguiente ejemplo, se encuentra el propietario de la cuenta con la mayor cantidad de transferencias entrantes encadenando varias sentencias lineales de gráfico. Ten en cuenta que puedes usar la misma variable, account en este ejemplo, para hacer referencia al mismo elemento del gráfico en varias sentencias lineales.

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;

Resultado

account_id owner_name num_incoming_transfers
16 Lee 3

Funciones y expresiones

Puedes usar todas las funciones, operadores y condicionales en GoogleSQL, incluidas las funciones de agregación y otras funciones escalares en la consulta de gráficos de Spanner.

Spanner Graph también admite operadores y funciones integradas para los elementos de grafos.

Operadores y funciones integrados

Las siguientes funciones y operadores se usan comúnmente en GQL:

  • PROPERTY_EXISTS(n, birthday): Muestra si n expone la propiedad birthday.
  • LABELS(n): Muestra las etiquetas de n como se define en el esquema del gráfico.
  • PROPERTY_NAMES(n): Muestra los nombres de las propiedades de n.
  • TO_JSON(n): Muestra n en formato JSON. Para obtener más información, consulta la función TO_JSON.

En la siguiente consulta, se ilustra el predicado PROPERTY_EXISTS y la función LABELS. función TO_JSON, así como otras funciones integradas, como ARRAY_AGG y 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;

Resultado

is_blocked_property_exists name_property_exists etiquetas cuentas ubicación persona
falso true Persona ["Vacation Fund"] Adelaida, Australia {&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

Una subconsulta es una consulta anidada en otra consulta. En la siguiente lista, se enumeran las reglas de subconsulta de Spanner Graph:

  • Una subconsulta se encierra dentro de un par de llaves {}.
  • Una subconsulta puede comenzar con la cláusula GRAPH inicial para especificar el gráfico en el alcance. No es necesario que el gráfico especificado sea el mismo que se usa en la consulta externa.
  • Cuando se omite la cláusula GRAPH en la subconsulta, ocurre lo siguiente:
    • El grafo en el alcance se infiere del contexto de consulta externo más cercano.
    • La subconsulta debe comenzar con una declaración de coincidencia de patrones de grafos con el MATCH.
  • Una variable de patrón de gráfico declarada fuera del alcance de la subconsulta no se puede volver a declarar dentro de ella, pero se puede hacer referencia a ella en expresiones o funciones dentro de la subconsulta.

Usa una subconsulta para encontrar la cantidad total de transferencias de cada cuenta

En la siguiente consulta, se ilustra el uso de la subconsulta VALUE. La subconsulta se cierra entre llaves {} con el prefijo de la palabra clave VALUE. La consulta muestra el importe total de las transferencias iniciadas desde una cuenta.

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;

Resultado

name account_id total_transfer
Alex 7 400
Dana 20 700
Lee 16 300

Para obtener una lista de expresiones de subconsultas admitidas, consulta Subconsultas del gráfico de Spanner.

Parámetros de consulta

Puedes consultar Spanner Graph con parámetros. Para obtener más información, consulta la sintaxis y aprenderás a consultar datos con parámetros en las bibliotecas cliente de Spanner.

En la siguiente consulta, se ilustra el uso de los parámetros de consulta.

GRAPH FinGraph
MATCH (person:Person {id: @id})
RETURN person.name;

Consultar tablas y gráficos en conjunto

Puedes usar las consultas de grafos junto con SQL para acceder a información de tus gráficos y tablas juntos en una sola instrucción.

GRAPH_TABLE

El operador GRAPH_TABLE toma una consulta de gráfico lineal y muestra su resultado en un formato tabular que se puede integrar sin problemas en una consulta de SQL. Esta interoperabilidad te permite enriquecer los resultados de las consultas de gráficos con contenido que no es de gráficos y viceversa.

Por ejemplo, puedes crear una tabla de CreditReports e insertar algunos créditos informes, como se muestra en el siguiente ejemplo:

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);

Luego, identifica a las personas de interés a través de la coincidencia de patrones de gráficos en GRAPH_TABLE y une los resultados de la consulta de gráficos con la tabla CreditReports para acceder a la puntuación 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

¿Qué sigue?

Conoce las prácticas recomendadas para ajustar las consultas.