En esta página, se describe cómo trabajar con las instrucciones de gráfico en Spanner Graph.
En las bases de datos de gráficos, el tipo de datos de ruta de gráfico representa una secuencia de nodos intercalados con aristas y muestra cómo se relacionan estos nodos y aristas. Para obtener más información sobre el tipo de datos de ruta, consulta Tipo de ruta de gráfico.
Con el lenguaje de Spanner Graph (GQL), puedes crear rutas de acceso de gráficos y realizar consultas en ellas. Los ejemplos de este documento usan el mismo esquema de Spanner Graph que se encuentra en la página Configura y consulta Spanner Graph.
Cómo construir una ruta de gráfico
Para construir una ruta de gráfico, crea una variable de ruta en un patrón de gráfico o con la función PATH
.
Recomendamos que construyas una ruta de gráfico con la variable de ruta. El formato para crear una variable de ruta es el siguiente:
MATCH p = PATH_PATTERN
Para obtener más información, consulta Patrón de gráfico.
Ejemplo
En el siguiente ejemplo, la consulta encuentra patrones de transferencias de dinero entre
cuentas dentro de FinGraph
.
GRAPH FinGraph
MATCH p = (src:Account {id: 16})-[t1:Transfers]->(mid:Account)-[t2:Transfers]->
(dst:Account {id: 7})
RETURN TO_JSON(p) AS full_path;
Resultado
full_path |
---|
[{"identifier": ..., "properties": {"id": 16, ...}, ...}, {"identifier": ..., "properties": {"amount": 300.0, ...}, ...}, ...}] |
El resultado indica que la consulta encontró el patrón Account -> Transfers -> Account
en la base de datos.
Cómo consultar una ruta de gráfico
Puedes usar las siguientes funciones específicas de la ruta para consultar una ruta de gráfico. Para obtener información más general sobre las consultas de Spanner Graph, consulta Descripción general de las consultas.
EDGES
La función EDGES
muestra todos los bordes de una ruta de gráfico. Para obtener semántica detallada, consulta EDGES
.
Ejemplo
Esta consulta encuentra una ruta entre dos cuentas que pasa por una cuenta intermedia.
Muestra la cantidad del segundo borde Transfers
en la ruta, que puede estar entre src
y mid
o entre mid
y dst
.
GRAPH FinGraph
MATCH p = (src:Account {id: 7})-[t1:Transfers]->{1,3}(mid:Account)-[t2:Transfers]->
{1,3}(dst:Account {id: 16})
LET second_edge = EDGES(p)[1]
RETURN DISTINCT src.id AS src, dst.id AS dst, second_edge.amount AS second_edge_amount;
Resultado
src | DST | second_edge_amount |
---|---|---|
7 | 16 | 300 |
NODES
La función NODES
muestra todos los nodos de una ruta de acceso de grafo. Para obtener semántica detallada, consulta NODES
.
Ejemplo
Esta consulta encuentra la ruta del gráfico de dos transferencias y, luego, muestra una lista JSON que representa la ruta.
GRAPH FinGraph
MATCH p = (src:Account)-[t1:Transfers]->(mid:Account)-[t2:Transfers]->(dst:Account)
RETURN TO_JSON(NODES(p)) AS nodes;
Resultado
nodos |
---|
[{"identifier": "...", "properties": {"id": 16}, ...}, {"identifier": "...", "properties": {"id": 20, ...}, ...] |
… |
PATH_FIRST
La función PATH_FIRST
encuentra el primer nodo en una ruta de acceso de gráfico. Para obtener semántica detallada, consulta PATH_FIRST
.
Ejemplo
Esta consulta encuentra el primer nodo en una ruta de gráfico de dos transferencias. Devuelve la etiqueta del nodo Account
y el sobrenombre de la cuenta.
GRAPH FinGraph
MATCH p = -[:Transfers]->{1,3}(dst:Account{id: 7})
RETURN DISTINCT PATH_FIRST(p).id AS can_reach_target;
Resultado
can_reach_target |
---|
7 |
16 |
20 |
PATH_LAST
La función PATH_LAST
encuentra el último nodo en una ruta de gráfico. Para obtener semántica detallada, consulta PATH_LAST
.
Ejemplo
Esta consulta encuentra el último nodo en una ruta de gráfico de dos transferencias. Muestra la etiqueta del nodo Account
y el sobrenombre de la cuenta.
GRAPH FinGraph
MATCH p =(start:Account{id: 7})-[:Transfers]->{1,3}
RETURN DISTINCT PATH_LAST(p).id as can_reach_target;
Resultado
can_reach_target |
---|
7 |
16 |
20 |
PATH_LENGTH
La función PATH_LENGTH
encuentra la cantidad de aristas en una ruta de gráfico. Para obtener semántica detallada, consulta PATH_LENGTH
.
Ejemplo
Esta consulta encuentra la cantidad de aristas en una ruta de gráfico que contiene de una a tres transferencias.
GRAPH FinGraph
MATCH p = (src:Account)-[e:Transfers]->{1,3}(dst:Account)
RETURN PATH_LENGTH(p) AS num_transfers, COUNT(*) AS num_paths;
Resultado
num_transfers | num_paths |
---|---|
1 | 5 |
2 | 7 |
3 | 11 |
IS_ACYCLIC
La función IS_ACYCLIC
verifica si una ruta de gráfico tiene nodos repetidos. Muestra TRUE
si se encuentra una repetición; de lo contrario, muestra FALSE
. Para obtener semántica detallada, consulta IS_ACYCLIC
.
Ejemplo
Esta consulta verifica si esta ruta de acceso del gráfico tiene nodos repetidos.
GRAPH FinGraph
MATCH p = (src:Account)-[t1:Transfers]->(mid:Account)-[t2:Transfers]->(dst:Account)
RETURN IS_ACYCLIC(p) AS is_acyclic_path, src.id AS source_account_id,
mid.id AS mid_account_id, dst.id AS dst_account_id;
Resultado
is_acyclic_path | source_account_id | mid_account_id | dst_account_id |
---|---|---|---|
TRUE | 16 | 20 | 7 |
TRUE | 20 | 7 | 16 |
TRUE | 20 | 7 | 16 |
FALSO | 16 | 20 | 16 |
TRUE | 7 | 16 | 20 |
TRUE | 7 | 16 | 20 |
FALSO | 20 | 16 | 20 |
IS_TRAIL
La función IS_TRAIL
verifica si una ruta de gráfico tiene bordes repetidos. Muestra TRUE
si se encuentra una repetición; de lo contrario, muestra FALSE
. Para obtener semántica detallada, consulta IS_TRAIL
.
Ejemplo
Esta consulta verifica si esta ruta de acceso del gráfico tiene aristas repetidas.
GRAPH FinGraph
MATCH p = (src:Account)-[t1:Transfers]->(mid1:Account)-[t2:Transfers]->
(mid2:Account)-[t3:Transfers]->(dst:Account)
WHERE src.id < dst.id
RETURN IS_TRAIL(p) AS is_trail_path, t1.id AS t1_id, t2.id AS t2_id, t3.id AS t3_id;
Resultado
is_trail_path | t1_id | t2_id | t3_id |
---|---|---|---|
FALSO | 16 | 20 | 16 |
TRUE | 7 | 16 | 20 |
TRUE | 7 | 16 | 20 |
Modos de ruta de acceso
En Spanner Graph, el comportamiento predeterminado es mostrar todas las rutas, incluso las que tienen nodos y aristas repetidos. Puedes usar los siguientes modos de ruta para incluir o excluir rutas que tengan nodos y aristas repetidos. Para obtener una semántica detallada, consulta la documentación de Pathmode.
WALK
El modo de ruta WALK
muestra todas las rutas, incluidas las que tienen nodos y bordes repetidos. WALK
es el modo de ruta predeterminado.
Ejemplo
En la siguiente consulta, se muestra el uso del modo de ruta WALK
en un patrón de ruta no cuantificado. La primera ruta de los resultados usa el mismo borde para t1
y t3
.
GRAPH FinGraph
MATCH p = WALK (src:Account)-[t1:Transfers]->(mid1:Account)-[t2:Transfers]->
(mid2:Account)-[t3:Transfers]->(dst:Account)
WHERE src.id < dst.id
RETURN t1.id AS transfer1_id, t2.id AS transfer2_id, t3.id AS transfer3_id;
Resultado
transfer1_id | transfer2_id | transfer3_id |
---|---|---|
16 | 20 | 16 |
7 | 16 | 20 |
7 | 16 | 20 |
ACYCLIC
El modo de ruta ACYCLIC
filtra las rutas que tienen nodos repetidos.
Ejemplo
En la siguiente consulta, se muestra el uso del modo de ruta ACYCLIC
en un patrón de ruta no cuantificado.
Se filtra la ruta con nodos src
y dst
iguales.
GRAPH FinGraph
MATCH p = ACYCLIC (src:Account)-[t1:Transfers]->(mid:Account)-[t2:Transfers]->(dst:Account)
RETURN src.id AS account1_id, mid.id AS account2_id, dst.id AS account3_id;
Resultado
account1_id | account2_id | account3_id |
---|---|---|
20 | 7 | 16 |
20 | 7 | 16 |
7 | 16 | 20 |
7 | 16 | 20 |
16 | 20 | 7 |
TRAIL
El modo de ruta TRAIL
filtra las rutas que tienen bordes repetidos.
Ejemplo
En la siguiente consulta, se muestra el uso del modo de ruta TRAIL
en un patrón de ruta no cuantificado. Se filtra la ruta cuyas aristas t1
y t3
son iguales.
GRAPH FinGraph
MATCH p = TRAIL (src:Account)-[t1:Transfers]->(mid1:Account)-[t2:Transfers]->
(mid2:Account)-[t3:Transfers]->(dst:Account)
RETURN
t1.id AS transfer1_id, t2.id AS transfer2_id, t3.id AS transfer3_id;
Resultado
transfer1_id | transfer2_id | transfer3_id |
---|---|---|
16 | 20 | 7 |
16 | 20 | 7 |
20 | 7 | 16 |
20 | 7 | 16 |
7 | 16 | 20 |
7 | 16 | 20 |
7 | 16 | 20 |
7 | 16 | 20 |
20 | 16 | 20 |
Prefijo de búsqueda de ruta
Puedes usar un prefijo de búsqueda de ruta para restringir un patrón de ruta de acceso para que muestre la ruta más corta de cada partición de datos. Para obtener semántica detallada, consulta Prefijo de búsqueda de ruta.
ANY SHORTEST
El prefijo de búsqueda de ruta ANY SHORTEST
muestra la ruta más corta (la ruta con la menor cantidad de aristas) que coincide con el patrón de cada partición de datos. Si hay más de una ruta más corta por partición, muestra cualquiera de ellas.
Ejemplo
La siguiente consulta coincide con cualquier ruta entre cada par de [a, b]
.
GRAPH FinGraph
MATCH p = ANY SHORTEST (a:Account)-[t:Transfers]->{1,4}(b:Account)
WHERE a.is_blocked
LET total_amount = SUM(t.amount)
RETURN a.id AS account1_id, total_amount, b.id AS account2_id;
Resultado
account1_id | total_amount | account2_id |
---|---|---|
16 | 500 | 16 |
16 | 800 | 7 |
16 | 300 | 20 |
Reglas de conversión
Para obtener más información, consulta las reglas de conversión de GRAPH_PATH.
Ejemplo de caso de uso
En el siguiente ejemplo de caso de uso, verás que todas las cuentas se enrutaron a través de una a tres cuentas, desde el ID de cuenta 20
.
GRAPH FinGraph
MATCH p = (start:Account {id: 20})-[:Transfers]->{1,3}(dst:Account)
RETURN DISTINCT dst.id AS dst;
Resultado
DST |
---|
7 |
16 |
20 |
Sin embargo, una consulta que devuelve el ID de cuenta 20
podría ser demasiado amplia porque comienza con el ID de cuenta 20
. Para mostrar resultados más específicos, puedes forzar tu consulta para que muestre solo rutas de grafos acíclicos sin nodos repetidos.
Para ello, puedes hacer lo siguiente:
- Usa
MATCH p = ACYCLIC <path_pattern>
. - Aplica un filtro
IS_ACYCLIC(p)
en tu consulta
En la siguiente consulta, se usa MATCH p = ACYCLIC PATH_PATTERN
:
GRAPH FinGraph
MATCH p = ACYCLIC (start:Account {id: 20})-[:Transfers]->{1,3}(dst:Account)
RETURN DISTINCT dst.id AS dst;
Resultado
DST |
---|
7 |
16 |
Si quieres conocer la primera cuenta a través de la cual se transfiere el dinero, puedes ejecutar la siguiente consulta:
GRAPH FinGraph
MATCH p = ACYCLIC (start:Account {id: 20})(-[:Transfers]->
(nexts:Account)){1,3}(dst:Account)
RETURN dst.id AS dst, ARRAY_AGG(DISTINCT nexts[0].id) AS unique_starts;
Esta consulta no es convencional porque introduce una variable nueva dentro de la ruta cuantificada con nexts
para obtener el resultado. Con las variables de ruta, puedes
simplificar la consulta:
GRAPH FinGraph
MATCH p = ACYCLIC (start:Account {id: 20})-[:Transfers]->{1,3}(dst:Account)
RETURN dst.id AS dst, ARRAY_AGG(DISTINCT NODES(p)[OFFSET(1)].id) AS unique_starts;
El uso de NODES(p)
muestra todos los nodos a lo largo de la ruta. Como la primera cuenta de nodos se especifica como start
, la siguiente (en el primer desplazamiento) es la primera cuenta a través de la que se transfiere el dinero.
Resultado
DST | unique_starts |
---|---|
7 | 16, 7 |
Las rutas son más útiles cuando hay varias rutas cuantificadas. Puedes agregar una restricción que indique que las rutas encontradas desde start
deben pasar por el ID de la cuenta 7
:
GRAPH FinGraph
MATCH p = ACYCLIC (start:Account {id: 20})-[:Transfers]->
{1,3}(mid:Account {id: 7})-[:Transfers]->{1,3}(dst:Account)
RETURN dst.id AS dst,
ARRAY_AGG(DISTINCT NODES(p)[OFFSET(1)].id) AS unique_starts;
Aunque cambió la sentencia MATCH
, no es necesario que cambie el resto de la consulta. Sin usar variables de ruta, hay casos en los que no es posible que Spanner sepa de forma estática qué ruta cuantificada inspeccionar.
Con una variable de ruta, puedes obtener la suma de todas las transferencias:
GRAPH FinGraph
MATCH p = ACYCLIC (start:Account {id: 20})-[:Transfers]->
{1,3}(mid:Account {id: 7})-[:Transfers]->{1,3}(dst:Account)
LET all_transfers = EDGES(p)
LET transfer_amounts = SUM(all_transfers.amount)
RETURN dst.id AS dst,
ARRAY_AGG(DISTINCT NODES(p)[OFFSET(1)].id) AS participating_neighbor_nodes, transfer_amounts;
Resultado
DST | participating_neighbor_nodes | transfer_amounts |
---|---|---|
16 | 7 | 600 |
16 | 7 | 800 |