Escritura de consultas de patrones de grafos en Microsoft Fabric

La coincidencia de patrones de grafos le permite describir la estructura de los datos que desea encontrar mediante la sintaxis visual intuitiva. En lugar de combinar tablas, se escriben patrones que parecen las propias relaciones: nodos conectados por bordes. En este artículo se muestra cómo escribir consultas de patrones GQL para escenarios comunes en el grafo en Microsoft Fabric.

En los ejemplos se usa el conjunto de datos de ejemplo de red social. Para obtener una referencia de sintaxis de patrón completa, consulte Patrones de grafos de GQL.

Utiliza este artículo para aprender a construir y combinar patrones de nodos, aristas y caminos. Para tareas listas para adaptar, como encontrar vecinos o entidades sin relaciones, véase Escribir consultas GQL comunes. Para filtrado, agrupación y flujo de trabajo agregado, véase Filtrar y agregar datos de grafos.

Prerequisites

Coincidencia de relaciones directas

Un patrón básico coincide con un tipo de nodo, un tipo perimetral específico y otro tipo de nodo. La sintaxis es similar a un diagrama de la relación.

Por ejemplo, para encontrar hasta 100 personas emparejadas con la empresa en la que trabajan:

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName, p.lastName, c.name
LIMIT 100

Use un patrón de borde no direccionado cuando no sepa o no le interese la dirección. Por ejemplo, para buscar hasta 100 conocidos mutuos independientemente de quién inició la conexión:

MATCH (a:Person)-[:knows]-(b:Person)
RETURN a.firstName, b.firstName
LIMIT 100

Note

Actualmente, el grafo no admite la creación de aristas no dirigidas, pero puede consultar aristas en cualquier dirección mediante la sintaxis -[:label]-.

Filtrar patrones con WHERE insertado

Coloca WHERE dentro del patrón cuando una condición define qué nodo o arista puede participar en el emparejamiento. Utiliza una condición de nivel de sentencia MATCH ... WHERE para filtrar posteriormente la coincidencia completa, o una cláusula FILTER independiente cuando la condición se aplique a la fila producida por una instrucción anterior. La colocación de predicados puede cambiar los resultados del camino más corto. Para más información, consulta Colocar predicados antes o después de la selección de caminos.

Por ejemplo, para buscar personas nacidas antes de 1990 que trabajan en una empresa cuyo nombre comienza por "A":

MATCH (p:Person WHERE p.birthday < 19900101)-[:workAt]->(c:Company WHERE c.name STARTS WITH 'A')
RETURN p.firstName, p.lastName, c.name

Filtre por las propiedades perimetrales para restringir qué relaciones coinciden. Por ejemplo, para mostrar solo a las personas que comenzaron a trabajar en una empresa en 2010 o posteriormente:

MATCH (p:Person)-[w:workAt WHERE w.workFrom >= 2010]->(c:Company)
RETURN p.firstName, c.name, w.workFrom

Coincidencia de relaciones de varios saltos

Use patrones de longitud variable para recorrer varios saltos en una expresión. Especifique el número mínimo y máximo de saltos con {min,max} sintaxis.

Por ejemplo, para encontrar hasta 100 personas accesibles dentro de dos a cuatro grados de amistad de Alice:

MATCH (src:Person WHERE src.firstName = 'Alice')-[:knows]->{2,4}(dst:Person)
RETURN dst.firstName, dst.lastName
LIMIT 100

Para encontrar hasta 100 conexiones inmediatas y de segundo grado (uno o dos saltos) de Alice:

MATCH (src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,2}(dst:Person)
RETURN DISTINCT dst.firstName, dst.lastName
LIMIT 100

Control del recorrido con modos de recorrido

Por defecto, GQL utiliza WALK, lo que permite nodos y aristas repetidos. Usa otro modo de ruta cuando necesites una exclusividad más estricta de los elementos.

Modo de ruta Comportamiento Use cuando...
WALK Permite nodos y aristas repetidos (por defecto) Se quieren todos los recorridos coincidentes dentro de un límite finito.
TRAIL No hay aristas repetidas Quieres evitar volver a seguir el mismo borde, pero el mismo nodo puede aparecer a través de diferentes bordes.
SIMPLE No hay nodos repetidos salvo un nodo compartido de inicio y fin, y no hay aristas repetidas Quieres que ningún nodo aparezca más de una vez en medio de un camino, pero permite que los caminos se cierren y regresen al inicio. Resulta útil para detectar bucles.
ACYCLIC No hay nodos ni aristas repetidos Debe garantizar que ningún nodo aparezca en ninguna parte del camino más de una vez. Se usa para jerarquías estrictas, linaje o cualquier recorrido en el que volver a visitar un nodo produciría resultados incorrectos.

WALK es el modo más permisivo y ACYCLIC es el más restrictivo.

Para SIMPLE y ACYCLIC, la unicidad de aristas se deduce de la unicidad del nodo. Un SIMPLE camino puede cerrarse volviendo a su primer nodo, pero aún así no puede reutilizar un borde.

Para ilustrar la diferencia, considere la ruta alice → Bob → Carol → Bob:

  • WALK : permite esta ruta de acceso. Los nodos y los bordes pueden repetirse libremente.
  • TRAIL : permite esta ruta de acceso. Bob aparece dos veces, pero cada borde usado es una relación diferente (Alice→Bob y Carol→Bob son bordes distintos), por lo que no se repite ningún borde.
  • SIMPLE : bloquea esta ruta de acceso. Bob aparece más de una vez y SIMPLE solo permite repetir un nodo si es tanto el inicio como el final del camino (un ciclo cerrado). Aquí Alice es el principio y Bob es el final, por lo que no se aplica ninguna excepción.
  • ACÍCLICO — bloquea esta trayectoria. Bob aparece más de una vez en cualquier parte de la ruta de acceso.

En el ejemplo siguiente se muestra cómo usar TRAIL para contar cuántas rutas de acceso distintas conducen a cada una de las primeras 100 personas a las que se puede acceder en la red de Alice en cuatro saltos:

MATCH TRAIL (src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,4}(dst:Person)
LET personId = dst.id
RETURN personId, dst.firstName, dst.lastName, count(*) AS pathCount
GROUP BY personId, dst.firstName, dst.lastName
ORDER BY pathCount DESC
LIMIT 100

Use ACYCLIC para devolver hasta 100 personas accesibles desde Alice dentro de cuatro saltos, donde cada persona en el camino es única:

MATCH ACYCLIC (src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,4}(dst:Person)
RETURN dst.firstName, dst.lastName
LIMIT 100

El modo de coincidencia por defecto REPEATABLE ELEMENTS permite reutilizar una arista mediante caminos separados en el mismo patrón de gráfico. Use DIFFERENT EDGES o DIFFERENT RELATIONSHIPS cuando la vinculación de cada arista a lo largo de todas las rutas deba ser diferente:

MATCH DIFFERENT EDGES
  (p:Person)-[:knows]->(friend:Person),
  (p)-[:knows]->(other:Person)
RETURN p.firstName, friend.firstName, other.firstName
LIMIT 100

Regresa el camino más corto

ALL es la búsqueda de rutas predeterminada y devuelve todas las rutas correspondientes. Úsalo ANY SHORTEST para devolver un camino más corto para cada par origen-destino. La siguiente consulta encuentra un camino más corto de Alicia a Bob:

MATCH p = ANY SHORTEST
  (src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,4}
  (dst:Person WHERE dst.firstName = 'Bob')
RETURN p, path_length(p) AS hopCount

Cuando varios caminos más cortos empatan, cuál camino se devuelve no es determinista. No se admiten las búsquedas de rutas ALL SHORTEST y ANY.

La colocación de predicados puede cambiar el resultado de ANY SHORTEST. Los predicados de nodo en línea y de arista limitan qué rutas pueden considerarse válidas, mientras que un postfiltro puede eliminar la ruta seleccionada sin elegir en su lugar una ruta más larga. Véase Colocar los predicados de posición antes o después de la selección de rutas.

Sugerencia

Prefiero un límite superior finito para el coste de consulta predecible. No se soportan patrones ALL WALK ilimitados. Los patrones no acotados con TRAIL, SIMPLE o ACYCLIC finalizan debido a la unicidad de los elementos, pero aun así pueden devolver muchos caminos. Unbounded ANY SHORTEST WALK solo soporta formas de consulta específicas. Consulte Limitaciones actuales.

Uso de la reutilización de variables para expresar entidades compartidas

La reutilización de la misma variable en dos partes de un patrón crea una restricción de igualdad implícita: ambas referencias deben coincidir con el mismo nodo. Esta técnica le permite expresar "buscar entidades conectadas a través de una tercera entidad compartida".

Por ejemplo, para encontrar hasta 100 pares de personas que se conocen entre sí y trabajan en la misma empresa:

MATCH (c:Company)<-[:workAt]-(a:Person)-[:knows]-(b:Person)-[:workAt]->(c)
RETURN a.firstName, b.firstName, c.name
LIMIT 100

La variable c se reutiliza para ambos workAt destinos, por lo que la consulta solo devuelve pares en los que ambas personas se conocen entre sí y trabajan en la misma empresa.

Para encontrar hasta 100 pares de personas a las que les gustó la misma publicación:

MATCH (a:Person)-[:likes]->(post:Post)<-[:likes]-(b:Person)
WHERE a.id < b.id
RETURN a.firstName, b.firstName, post.id
LIMIT 100

Sugerencia

La WHERE a.id < b.id condición impide que los pares duplicados (Alice + Bob y Bob + Alice) aparezcan en los resultados.

Combinar varios patrones

Enumere varios patrones en un único MATCH, separados por comas. Reutiliza una variable cuando los patrones deben vincular el mismo elemento del grafo.

Por ejemplo, para encontrar hasta 100 personas junto con su lugar de trabajo y la ciudad en la que viven:

MATCH (p:Person)-[:workAt]->(c:Company),
      (p)-[:isLocatedIn]->(city:City)
RETURN p.firstName, c.name AS company, city.name AS city
LIMIT 100

La variable p compartida conecta los dos patrones. Cada fila de resultados representa a una persona con su empresa y ciudad.

Los patrones desconectados también son válidos, pero forman un producto cartesiano de sus coincidencias. Úsalos solo cuando necesites intencionadamente cada combinación. Para orientación de rendimiento, véase Usar variables compartidas para uniones eficientes.

Coincidencia de relaciones opcionales

Use OPTIONAL MATCH cuando es posible que una relación no exista para cada nodo. Las filas sin coincidencia se conservan con NULL valores similares a sql LEFT JOIN.

Por ejemplo, devuelva hasta 100 personas con su nombre de empresa, incluidas las personas sin empleador (es decir, que devuelven NULL para la columna de la empresa):

MATCH (p:Person)
OPTIONAL MATCH (p)-[:workAt]->(c:Company)
RETURN p.firstName, p.lastName, c.name AS company
LIMIT 100

Usa IS NULL después de OPTIONAL MATCH para encontrar hasta 100 personas que no trabajan en ninguna empresa.

MATCH (p:Person)
OPTIONAL MATCH (p)-[:workAt]->(c:Company)
FILTER c IS NULL
RETURN p.firstName, p.lastName
LIMIT 100