Descripción general de las consultas de gráficos
BigQuery Graph te permite escribir consultas de grafos para hacer coincidir patrones de nodos, bordes y rutas, y recorrer relaciones con el Graph Query Language (GQL).
En los ejemplos de este documento, se hace referencia a un grafo llamado FinGraph, que muestra
las relaciones entre las personas, las cuentas que poseen y las transferencias entre
cuentas. Para obtener información sobre la definición del gráfico, consulta
el ejemplo de FinGraph.
Estructura de la consulta
Una consulta de grafo consiste en el nombre del grafo, seguido de una o más instrucciones de consulta lineales. Cada consulta lineal contiene una o más declaraciones, que te permiten trabajar con datos de grafos para encontrar coincidencias de patrones, definir variables, filtrar y transformar datos intermedios, y devolver resultados. Ejecutas una consulta de grafo de la misma manera que ejecutas una consulta en SQL en BigQuery.
Coincidencia de patrones de grafos
La coincidencia de patrones de grafos busca patrones específicos dentro de tu grafo. Los patrones más básicos son los patrones de elementos, como los patrones de nodos que coinciden con nodos y los patrones de bordes que coinciden con bordes.
Patrones de nodos
Un patrón de nodo coincide con los nodos de tu grafo. Este patrón contiene paréntesis coincidentes, que pueden incluir de forma opcional una variable de patrón de grafo, una expresión de etiqueta y filtros de propiedad.
Encuentra todos los nodos
La siguiente consulta devuelve todos los nodos del grafo. La variable n, una variable de patrón de grafo, se vincula a los nodos coincidentes. En este caso, el patrón de nodo
coincide con todos los nodos del grafo.
GRAPH graph_db.FinGraph
MATCH (n)
RETURN LABELS(n) AS label, n.id;
Esta consulta devuelve label y id:
label |
id |
|---|---|
Account |
7 |
Account |
16 |
Account |
20 |
Person |
1 |
Person |
2 |
Person |
3 |
Busca 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 devuelve la etiqueta y algunas propiedades de los nodos que coinciden.
GRAPH graph_db.FinGraph
MATCH (p:Person)
RETURN LABELS(p) AS label, p.id, p.name;
Esta consulta devuelve las siguientes propiedades de los nodos que coinciden:
label |
id |
name |
|---|---|---|
Person |
1 |
Alex |
Person |
2 |
Dana |
Person |
3 |
Lee |
Encuentra 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. Por ejemplo, la siguiente consulta coincide con todos los
nodos del grafo que tienen la etiqueta Person o Account. La variable de patrón de grafo n expone todas las propiedades de los nodos con la etiqueta Person o Account.
GRAPH graph_db.FinGraph
MATCH (n:Person|Account)
RETURN LABELS(n) AS label, n.id, n.birthday, n.create_time;
Ten en cuenta lo siguiente en los resultados de esta consulta:
- Todos los nodos tienen la propiedad
id. - Los nodos que coinciden con la etiqueta
Accounttienen la propiedadcreate_time, pero no tienen la propiedadbirthday. La propiedadbirthdayesNULLpara estos nodos. - Los nodos que coinciden con la etiqueta
Persontienen la propiedadbirthday, pero no la propiedadcreate_time. La propiedadcreate_timeesNULLpara estos nodos.
label |
id |
birthday |
create_time |
|---|---|---|---|
Account |
7 |
NULL |
2020-01-10T14:22:20.222Z |
Account |
16 |
NULL |
2020-01-28T01:55:09.206Z |
Account |
20 |
NULL |
2020-02-18T13:44:20.655Z |
Person |
1 |
1991-12-21T08:00:00Z |
NULL |
Person |
2 |
1980-10-31T08:00:00Z |
NULL |
Person |
3 |
1986-12-07T08:00:00Z |
NULL |
Encuentra todos los nodos que coinciden con la expresión de etiqueta y el filtro de propiedad
La siguiente consulta coincide con todos los nodos del grafo que tienen la etiqueta Person
y la propiedad id igual a 1:
GRAPH graph_db.FinGraph
MATCH (p:Person {id: 1})
RETURN LABELS(p) AS label, p.id, p.name, p.birthday;
El resultado es similar al siguiente:
label |
id |
name |
birthday |
|---|---|---|---|
Person |
1 |
Alex |
1991-12-21T08:00:00Z |
Puedes usar la cláusula WHERE para formar condiciones de filtrado más complejas en
etiquetas y propiedades.
En la siguiente consulta, se usa la cláusula WHERE para filtrar los nodos en los que
la propiedad birthday es anterior a 1990-01-10:
GRAPH graph_db.FinGraph
MATCH (p:Person WHERE p.birthday < '1990-01-10')
RETURN LABELS(p) AS label, p.name, p.birthday;
El resultado es similar al siguiente:
label |
name |
birthday |
|---|---|---|
Person |
Dana |
1980-10-31T08:00:00Z |
Person |
Lee |
1986-12-07T08:00:00Z |
Patrones perimetrales
Un patrón de arista coincide con las aristas o relaciones entre los nodos. Los patrones de borde se
encierran entre corchetes ([]) y, además, incluyen símbolos como -, -> o
<- para indicar direcciones. Un patrón de borde puede incluir, de forma opcional, una variable de patrón de grafo para vincularla a los bordes coincidentes.
Encuentra todas las aristas con etiquetas que coincidan
Esta consulta devuelve todas las aristas del grafo con la etiqueta Transfers. La consulta
vincula la variable del patrón de grafo e con las aristas que coinciden.
GRAPH graph_db.FinGraph
MATCH -[e:Transfers]->
RETURN e.Id as src_account, e.order_number;
El resultado es similar al siguiente:
src_account |
order_number |
|---|---|
7 |
304330008004315 |
7 |
304120005529714 |
16 |
103650009791820 |
20 |
304120005529714 |
20 |
302290001255747 |
Encuentra todos los bordes que coincidan con la expresión de etiqueta y el filtro de propiedad
El patrón de borde en la siguiente consulta usa una expresión de etiqueta y un filtro de propiedad
para encontrar todos los bordes etiquetados como Transfers que coincidan con un número de pedido
especificado:
GRAPH graph_db.FinGraph
MATCH -[e:Transfers {order_number: "304120005529714"}]->
RETURN e.Id AS src_account, e.order_number;
El resultado es similar al siguiente:
src_account |
order_number |
|---|---|
7 |
304120005529714 |
20 |
304120005529714 |
Encuentra todos los bordes con cualquier patrón de borde de dirección
Puedes usar el patrón de arista any direction (-[]-) en una consulta para hacer coincidir aristas
en cualquier dirección. En la siguiente consulta, se encuentran todas las transferencias con una cuenta
bloqueada:
GRAPH graph_db.FinGraph
MATCH (account:Account)-[transfer:Transfers]-(:Account {is_blocked:true})
RETURN transfer.order_number, transfer.amount;
El resultado es similar al siguiente:
order_number |
amount |
|---|---|
304330008004315 |
300 |
304120005529714 |
100 |
103650009791820 |
300 |
302290001255747 |
200 |
Patrones de ruta de acceso
Un patrón de ruta de acceso se crea a partir de patrones de nodos y bordes alternados.
Encuentra todas las rutas de acceso desde un nodo específico con un patrón de ruta de acceso
La siguiente consulta busca todas las transferencias a una cuenta iniciadas desde una cuenta
que pertenece a Person con id igual a 2.
Cada resultado coincidente representa una ruta de acceso desde un nodo Person cuando id es igual a
2 a través de un nodo Account conectado con un borde Owns,
en otro nodo Account con un borde Transfers.
GRAPH graph_db.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;
El resultado es similar al siguiente:
sender_id |
from_id |
to_id |
|---|---|---|
2 |
20 |
7 |
2 |
20 |
16 |
Patrones de ruta de acceso cuantificados
Un patrón cuantificado repite un patrón dentro de un rango especificado.
Cómo hacer coincidir un patrón de borde cuantificado
Para encontrar rutas de acceso de una longitud variable, puedes aplicar un cuantificador a un patrón de
arista. En la siguiente consulta, se demuestra esto encontrando cuentas de destino
que están a una o tres transferencias de un Account de origen con un valor id
de 7.
La consulta aplica el cuantificador {1, 3} al patrón de borde
-[e:Transfers]->. Esto indica a la consulta que busque coincidencias con rutas de acceso que repitan el
patrón de borde Transfers una, dos o tres veces. La cláusula WHERE se usa para
excluir la cuenta de origen de los resultados. La función ARRAY_LENGTH se usa para acceder al e group variable.
GRAPH graph_db.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;
El resultado es similar al siguiente:
src_account_id |
path_length |
dst_account_id |
|---|---|---|
7 |
1 |
16 |
7 |
1 |
16 |
7 |
3 |
16 |
7 |
3 |
16 |
7 |
2 |
20 |
7 |
2 |
20 |
Algunas filas de los resultados se repiten. Esto se debe a que pueden existir varias rutas de acceso que coincidan con el patrón entre los mismos nodos de origen y destino, y la consulta las devuelve todas.
Haz coincidir un patrón de ruta de acceso cuantificado
La siguiente consulta encuentra rutas entre nodos Account con uno o dos
bordes Transfers a través de cuentas intermedias que están bloqueadas.
El patrón de ruta de acceso entre paréntesis se cuantifica y su cláusula WHERE especifica
las condiciones para el patrón repetido.
GRAPH graph_db.FinGraph
MATCH
(src:Account)
((a:Account)-[:Transfers]->(b:Account {is_blocked:true}) WHERE a != b){1,2}
-[:Transfers]->(dst:Account)
RETURN src.id AS src_account_id, dst.id AS dst_account_id;
El resultado es similar al siguiente:
src_account_id |
dst_account_id |
|---|---|
7 |
20 |
7 |
20 |
20 |
20 |
Variables de grupo
Una variable de patrón de grafo declarada en un patrón cuantificado se convierte en una variable de grupo cuando se accede a ella fuera de ese patrón. Luego, se vincula a un array de elementos de gráfico coincidentes.
Puedes acceder a una variable de grupo como un array. Sus elementos de gráfico se conservan en el orden de su aparición en las rutas de acceso coincidentes. Puedes agregar una variable de grupo con la agregación horizontal.
Variable de grupo de acceso
En el siguiente ejemplo, se accede a la variable e de la siguiente manera:
- Como una variable de patrón de grafo vinculada a un solo borde en la cláusula
WHEREe.amount > 100cuando está dentro del patrón cuantificado. - Como una variable de grupo vinculada a un array de elementos de borde en
ARRAY_LENGTH(e)en la sentenciaRETURNcuando está fuera del patrón cuantificado. - Como una variable de grupo vinculada a un array de elementos de borde, que se agrega
por
SUM(e.amount)fuera del patrón cuantificado. Este es un ejemplo de agregación horizontal.
GRAPH graph_db.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;
El resultado es similar al siguiente:
src_account_id |
path_length |
total_amount |
dst_account_id |
|---|---|---|---|
7 |
1 |
300 |
16 |
7 |
2 |
600 |
20 |
Prefijos de búsqueda de rutas de acceso
Para limitar las rutas de acceso coincidentes dentro de los grupos que comparten nodos de origen y destino,
puedes usar el prefijo de búsqueda de ruta de acceso
ANY, ANY SHORTEST o ANY CHEAPEST.
Solo puedes aplicar estos prefijos antes de un patrón de ruta de acceso completo y no puedes
aplicarlos entre paréntesis.
Coincidencia con ANY
En la siguiente consulta, se encuentran todas las cuentas únicas accesibles que están a una o dos
Transfers de un nodo Account determinado.
El prefijo de búsqueda de ruta de acceso ANY garantiza que la consulta devuelva solo una ruta de acceso
entre un par único de nodos src y dst Account. En el siguiente
ejemplo, aunque puedes llegar al nodo Account con {id: 16} en dos
rutas de acceso diferentes desde el nodo Account de origen, la consulta devuelve solo una ruta de acceso.
GRAPH graph_db.FinGraph
MATCH ANY (src:Account {id: 7})-[e:Transfers]->{1,2}(dst:Account)
LET ids_in_path = ARRAY_CONCAT(ARRAY_AGG(e.Id), [dst.Id])
RETURN src.id AS src_account_id, dst.id AS dst_account_id, ids_in_path;
El resultado es similar al siguiente:
src_account_id |
dst_account_id |
ids_in_path |
|---|---|---|
7 |
16 |
7,16 |
7 |
20 |
7,16,20 |
Coincidencia con ANY SHORTEST
El prefijo de búsqueda de ruta de acceso ANY SHORTEST devuelve una sola ruta de acceso para cada par de
nodos de origen y destino, seleccionados de aquellos con la cantidad mínima de
aristas.
Por ejemplo, la siguiente consulta encuentra una de las rutas más cortas entre un
nodo Account con un valor id de 7 y un nodo Account con un valor id
de 20. La consulta considera rutas de acceso con uno a tres bordes Transfers.
GRAPH graph_db.FinGraph
MATCH ANY SHORTEST (src:Account {id: 7})-[e:Transfers]->{1, 3}(dst:Account {id: 20})
RETURN src.id AS src_account_id, dst.id AS dst_account_id, ARRAY_LENGTH(e) AS path_length;
El resultado es similar al siguiente:
src_account_id |
dst_account_id |
path_length |
|---|---|---|
7 |
20 |
2 |
Coincidencia con ANY CHEAPEST
El prefijo de búsqueda de ruta de acceso ANY CHEAPEST garantiza que, para cada par de cuentas de origen y
destino, la consulta devuelva solo una ruta de acceso con el costo de procesamiento total
mínimo.
En la siguiente consulta, se encuentra una ruta de acceso con el costo de procesamiento total mínimo entre
los nodos Account. Este costo se basa en la suma de la propiedad amount de los
bordes Transfers. La búsqueda considera rutas con uno a tres bordes de Transfers.
GRAPH graph_db.FinGraph
MATCH ANY CHEAPEST (src:Account)-[e:Transfers COST e.amount]->{1,3}(dst:Account)
LET total_cost = sum(e.amount)
RETURN src.id AS src_account_id, dst.id AS dst_account_id, total_cost;
El resultado es similar al siguiente:
src_account_id |
dst_account_id |
total_cost |
|---|---|---|
7 |
7 |
900 |
7 |
16 |
100 |
7 |
20 |
400 |
16 |
7 |
800 |
16 |
16 |
500 |
16 |
20 |
300 |
20 |
7 |
500 |
20 |
16 |
200 |
20 |
20 |
500 |
Patrones de grafos
Un patrón de grafo consta de uno o más patrones de ruta de acceso,
separados por una coma (,).
Los patrones de grafo pueden contener una cláusula WHERE, que te permite acceder a todas las variables de patrón de grafo
en los patrones de ruta de acceso para formar condiciones de filtrado. Cada patrón de ruta de acceso produce una colección de rutas de acceso.
Coincidencia con un patrón de grafo
La siguiente consulta identifica las cuentas intermediarias y sus propietarios involucrados en importes de transacciones que superan los 200, a través de los 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 encuentra rutas en las que la transferencia se produce de una cuenta a una cuenta bloqueada con una cuenta intermedia.
- El segundo patrón busca rutas de acceso desde una cuenta hasta la persona propietaria.
La variable interm actúa como un vínculo común entre los dos patrones de ruta de acceso, lo que requiere que interm haga referencia al mismo nodo de elemento en ambos patrones de ruta de acceso. Esto
crea una operación de unión equitativa basada en la variable interm.
GRAPH graph_db.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;
El resultado es similar al siguiente:
src_account_id |
dst_account_id |
interm_account_id |
owner_id |
|---|---|---|---|
20 |
16 |
7 |
1 |
Sentencias de consulta lineales
Puedes encadenar varias sentencias de grafo para formar una sentencia de consulta lineal. Las declaraciones se ejecutan en el mismo orden en que aparecen en la consulta.
Cada sentencia toma como entrada el resultado de la sentencia anterior. La entrada está vacía para la primera sentencia.
El resultado de la última sentencia es el resultado final.
Por ejemplo, puedes usar declaraciones de consulta lineales para encontrar la transferencia máxima a una cuenta bloqueada. La siguiente consulta busca la cuenta y su propietario con la transferencia saliente más grande a una cuenta bloqueada.
GRAPH graph_db.FinGraph
MATCH (src_account:Account)-[transfer:Transfers]->(dst_account:Account {is_blocked:true})
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 este proceso mostrando los resultados intermedios que se pasan entre cada sentencia. Para mayor brevedad, solo se muestran algunas propiedades.
| Afirmación | Resultado intermedio (abreviado) | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
MATCH
(src_account:Account)
-[transfer:Transfers]->
(dst_account:Account {is_blocked:true})
|
|
||||||||||||
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
|
|
El resultado es similar al siguiente:
| account_id | owner_name |
|---|---|
7 |
Alex |
Sentencia return
La declaración RETURN
especifica qué se debe devolver de los patrones que coinciden. Puede acceder
a variables de patrones de grafos y, además, incluir expresiones y otras cláusulas, como
ORDER BY y GROUP BY.
BigQuery Graph no admite la devolución de elementos de grafo como resultados de
consultas. Para devolver todo el elemento del grafo, usa la
función TO_JSON.
Devuelve elementos de grafo como JSON
GRAPH graph_db.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;
El resultado es similar al siguiente:
| 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"}} |
Redacta consultas más grandes con la palabra clave NEXT
Puedes encadenar varias sentencias de consulta lineal de grafo con la palabra clave NEXT.
La primera sentencia recibe una entrada vacía, y el resultado de cada sentencia
subsiguiente se convierte en la entrada de la siguiente.
En el siguiente ejemplo, se encuentra el propietario de la cuenta con la mayor cantidad de transferencias entrantes encadenando varias declaraciones lineales de grafo. Puedes usar la misma
variable, por ejemplo, account, para hacer referencia al mismo elemento del grafo en
varias declaraciones lineales.
GRAPH graph_db.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;
El resultado es similar al siguiente:
| account_id | owner_name | num_incoming_transfers |
|---|---|---|
16 |
Lee |
3 |
También puedes combinar sentencias de consulta lineales con operadores de conjunto.
Funciones y expresiones
Puedes usar todas las funciones de GoogleSQL (tanto las funciones agregadas como las escalares), los operadores y las expresiones condicionales en las consultas de grafos. BigQuery Graph también admite funciones de GQL y operadores de GQL que solo se pueden usar en consultas de grafos.
La siguiente consulta incluye una combinación de funciones y operadores de GQL y SQL dentro de una consulta de grafo:
GRAPH graph_db.FinGraph
MATCH (person:Person)-[o:Owns]->(account:Account)
WHERE person IS SOURCE OF o
RETURN person, ARRAY_AGG(account.nick_name) AS accounts
GROUP BY person
NEXT
RETURN
LABELS(person) AS labels,
accounts,
CONCAT(person.city, ", ", person.country) AS location,
TO_JSON(person) AS person
LIMIT 1;
El resultado es similar al siguiente:
| etiquetas | cuentas | ubicación | person |
|---|---|---|---|
Person |
["Vacation Fund"] |
Adelaide, Australia |
{"identifier":"mUZpbkdyYXBoLlBlcnNvbgB4kQI=","kind":"node","labels":["Person"],"properties":{"birthday":"1991-12-21T08:00:00Z","city":"Adelaide","country":"Australia","id":1,"name":"Alex"}} |
Subconsultas
Una subconsulta es una consulta que está anidada en otra consulta. Las siguientes reglas se aplican a las subconsultas dentro de las consultas de grafo:
- Una subconsulta se encierra entre un par de llaves
{}. - Una subconsulta comienza con una cláusula
GRAPHpara especificar el grafo en el alcance. No es necesario que el grafo especificado sea el mismo que el que se usa en la consulta externa. - Una variable de patrón de grafo declarada fuera del alcance de la subconsulta no se puede volver a declarar dentro de la subconsulta, 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
encierra entre llaves {} con el prefijo de la palabra clave VALUE. La consulta devuelve la cantidad total
de transferencias iniciadas desde una cuenta.
GRAPH graph_db.FinGraph
MATCH (p:Person)-[:Owns]->(account:Account)
RETURN p.name, account.id AS account_id, VALUE {
GRAPH graph_db.FinGraph
MATCH (a:Account)-[transfer:Transfers]->(:Account)
WHERE a = account
RETURN COUNT(transfer) AS num_transfers
} AS num_transfers;
El resultado es similar al siguiente:
| nombre | account_id | num_transfers |
|---|---|---|
Alex |
7 |
2 |
Dana |
20 |
2 |
Lee |
16 |
1 |
Para obtener una lista de las expresiones de subconsulta admitidas, consulta Subconsultas de BigQuery Graph.
Parámetros de consulta
Puedes consultar BigQuery Graph con parámetros. Para obtener más información, consulta la sintaxis y aprende a ejecutar consultas parametrizadas.
La siguiente consulta coincide con los nodos Person que tienen un valor id que coincide con
un parámetro de consulta:
GRAPH graph_db.FinGraph
MATCH (person:Person {id: @id})
RETURN person.name;
Consulta gráficos y tablas juntos
Puedes combinar consultas de grafos y consultas en SQL con el
operador GRAPH_TABLE.
El operador GRAPH_TABLE toma una consulta de grafo lineal y devuelve su resultado en
un formato tabular que se puede integrar en una consulta en SQL. Esta interoperabilidad
te permite enriquecer los resultados de las consultas de grafos con contenido que no es de grafos y viceversa.
Por ejemplo, puedes crear una tabla CreditReports y, luego, insertar algunos informes de crédito,
como se muestra en el siguiente ejemplo:
CREATE TABLE graph_db.CreditReports (
person_id INT64 NOT NULL,
create_time TIMESTAMP NOT NULL,
score INT64 NOT NULL,
PRIMARY KEY (person_id, create_time) NOT ENFORCED
);
INSERT INTO graph_db.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);
A continuación, puedes identificar personas específicas a través de la coincidencia de patrones de grafos en
GRAPH_TABLE y unir los resultados de la consulta de grafos con la tabla CreditReports para
recuperar las calificaciones crediticias.
SELECT
gt.person.id,
credit.score AS latest_credit_score
FROM GRAPH_TABLE(
graph_db.FinGraph
MATCH (person:Person)-[:Owns]->(:Account)-[:Transfers]->(account:Account {is_blocked:true})
RETURN DISTINCT person
) AS gt
JOIN graph_db.CreditReports AS credit
ON gt.person.id = credit.person_id
ORDER BY credit.create_time;
El resultado es similar al siguiente:
| person_id | latest_credit_score |
|---|---|
1 |
700 |
2 |
800 |
Prácticas recomendadas
Puedes optimizar el rendimiento de las consultas estructurándolas de modo que se minimice la cantidad de datos analizados y la cantidad de resultados intermedios.
Inicia el recorrido de la ruta desde los nodos de cardinalidad baja
Para mantener pequeños los conjuntos de resultados intermedios y acelerar la ejecución de las consultas, escribe tus
consultas de grafo de modo que el recorrido de la ruta comience desde nodos de cardinalidad más baja,
independientemente de la dirección del recorrido de la ruta. La siguiente sentencia MATCH usa filtros de propiedades para reducir la cantidad de nodos de inicio posibles en lugar de calcular todas las coincidencias y, luego, filtrar:
MATCH (p:Person {id: 10})-[own:Owns]->(a:Account)
Esto es especialmente importante para las consultas de rutas cuantificadas:
MATCH (p:Person {id: 10})-[own:Owns]->{1,3}(a:Account)
Usa el recorrido de ruta direccional
Los esquemas de BigQuery Graph son direccionales, lo que significa que cada
arista tiene un nodo de origen y un nodo de destino. Aunque la sintaxis de consulta de grafos
permite el recorrido de rutas en cualquier dirección (por ejemplo, -[edge]-), recomendamos
usar el recorrido de rutas direccional (por ejemplo, -[edge]-> o
<-[edge]-) para obtener un mejor rendimiento. Cualquier recorrido de ruta de dirección puede causar
pérdida de rendimiento.
La siguiente sentencia MATCH combina dos recorridos direccionales con
UNION ALL:
MATCH (a1:Account {id: 7})-[t:Transfers]->(a2:Account)
...
UNION ALL
...
MATCH (a1:Account {id: 7})<-[t:Transfers]-(a2:Account)
Usa la sintaxis ANY o ANY SHORTEST para las verificaciones de conectividad
Las consultas de rutas cuantificadas pueden devolver rutas duplicadas entre los nodos de origen y
los nodos de destino. Si tu objetivo es verificar la conectividad y no necesitas
todas las rutas posibles, usa ANY o ANY SHORTEST para reducir los cálculos redundantes
y mejorar la eficiencia de la búsqueda de rutas. Por ejemplo, la siguiente
sentencia MATCH usa ANY SHORTEST para mantener solo una ruta de acceso entre cada par
de nodos:
MATCH ANY SHORTEST (a1:Account)-[t:Transfers]->{1,3}(a2:Account)
Especifica etiquetas de forma explícita
Si se omiten las etiquetas de nodo o de borde en una consulta, BigQuery Graph enumera todas las etiquetas de nodo y de borde que cumplen con los requisitos. Esta enumeración puede hacer que se analicen más etiquetas de las necesarias. Para evitar esto, especifica etiquetas para todos los nodos y bordes de tu consulta siempre que sea posible.
Por ejemplo, en la siguiente consulta, se especifican las etiquetas Account y Transfers:
GRAPH graph_db.FinGraph
MATCH (a1:Account)-[t:Transfers]->(a2:Account)
RETURN COUNT(*) AS num_transfers;
Evita omitir etiquetas, ya que podría analizar otras relaciones innecesarias
entre nodos. En la siguiente consulta, a1 puede representar una cuenta o una
persona, y t puede representar una transferencia o la propiedad de una cuenta.
GRAPH graph_db.FinGraph
MATCH (a1)-[t]->(a2)
RETURN COUNT(*) AS num_transfers;
Usa una sola sentencia MATCH
BigQuery Graph te permite incluir varias declaraciones MATCH en
una sola consulta de grafo. Estas sentencias se conectan mediante variables declaradas varias veces
que representan el mismo nodo o borde. Sin embargo, usar varias instrucciones MATCH
puede disminuir los beneficios de cardinalidad en las instrucciones. Para obtener un mejor
rendimiento, usa una sola sentencia MATCH.
Por ejemplo, las siguientes consultas son equivalentes, pero la primera tiene un mejor rendimiento porque usa una sola sentencia MATCH:
-- Preferred syntax.
GRAPH graph_db.FinGraph
MATCH
(p:Person {id: 1})-[o:Owns]->
(a:Account)-[t:Transfers]->(a2:Account)
RETURN o.account_id, t.amount;
-- Avoid this syntax.
GRAPH graph_db.FinGraph
MATCH (p:Person {id: 1})-[o:Owns]->(a:Account)
MATCH (a:Account)-[t:Transfers]->(a2:Account)
RETURN o.account_id, t.amount;
Limita los bordes recorridos desde los nodos de cardinalidad alta
Cuando consultas grafos, algunos nodos pueden tener una cantidad significativamente mayor de aristas entrantes o salientes en comparación con otros nodos. Estos nodos de alta cardinalidad a veces se denominan supernodos o nodos centrales. Los supernodos pueden causar problemas de rendimiento, ya que los recorridos a través de ellos pueden implicar el procesamiento de grandes cantidades de datos, lo que genera un sesgo de datos y tiempos de ejecución prolongados.
Para optimizar una consulta de un grafo con supernodos, usa la
función ROW_NUMBER()
dentro de una cláusula FILTER o WHERE en MATCH para limitar la
cantidad de bordes que la consulta recorre desde o hacia un nodo. Esta técnica es
especialmente útil cuando no necesitas una enumeración completa de todas
las conexiones desde o hacia un supernodo.
Por ejemplo, si algunas cuentas de FinGraph tienen una gran cantidad de
transacciones, puedes usar ROW_NUMBER() para limitar la cantidad de aristas de Transfers
que se deben considerar para cada Account y evitar una consulta ineficiente:
GRAPH graph_db.FinGraph
MATCH (a1:Account)-[e1:Transfers WHERE e1 IN {
GRAPH graph_db.FinGraph
-- Sample 5 edges per source node
MATCH -[selected_e:Transfers]->
FILTER ROW_NUMBER() OVER (
PARTITION BY SOURCE_NODE_ID(selected_e)) < 5
RETURN selected_e
}]->{1,3}(a2:Account)
RETURN COUNT(*) AS cnt;
Muestrea nodos o bordes intermedios en consultas de varios saltos
Puedes mejorar la eficiencia de las consultas con ROW_NUMBER() para muestrear
nodos intermedios en consultas de varios saltos. Esta técnica limita la cantidad de
rutas de acceso que la consulta considera para cada nodo
intermedio. Para ello, divide una consulta de varios saltos en varias declaraciones MATCH
separadas por NEXT y aplica ROW_NUMBER() en el punto medio en el que necesites
tomar muestras:
GRAPH graph_db.FinGraph
MATCH (a1:Account)-[e1:Transfers]->(a2:Account)
-- Sample 5 destination nodes per a1 source node
FILTER ROW_NUMBER() OVER (PARTITION BY ELEMENT_ID(a1)) < 5
RETURN a1, a2
NEXT
MATCH (a2)-[e2:Transfers]->(a3:Account)
RETURN a1.id AS src_id, a2.id AS mid_id, a3.id AS dst_id;
¿Qué sigue?
- Obtén información para crear y consultar un grafo.
- Obtén más información para diseñar un esquema de grafo.
- Obtén información para visualizar los resultados de las consultas.