Gravar consultas de padrão de grafo no Microsoft Fabric

A correspondência de padrões de grafo permite descrever a estrutura dos dados que você deseja encontrar usando sintaxe visual intuitiva. Em vez de unir tabelas, você escreve padrões que se parecem com as próprias relações - nós conectados por bordas. Este artigo mostra como escrever consultas de padrão GQL para cenários comuns no grafo em Microsoft Fabric.

Os exemplos usam o conjunto de dados de exemplo de rede social. Para uma referência completa da sintaxe de padrões, consulte padrões de grafo GQL.

Use este artigo para aprender como construir e combinar padrões de nó, aresta e caminho. Para tarefas prontas para adaptação, como encontrar vizinhos ou entidades sem relações, veja Escrever consultas GQL comuns. Para fluxos de trabalho de filtragem, agrupamento e agregação, veja Filtrar e agregar dados de grafos.

Pré-requisitos

Relacionar relações diretas

Um padrão básico corresponde a um tipo de nó, um tipo de borda específico e outro tipo de nó. A sintaxe se parece com um diagrama da relação.

Por exemplo, para encontrar até 100 pessoas emparelhadas com a empresa em que trabalham:

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

Use um padrão de borda não redirecionado quando você não souber ou não se importar com a direção. Por exemplo, para encontrar até 100 conhecidos mútuos, independentemente de quem iniciou a conexão:

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

Note

Atualmente, o grafo não dá suporte à criação de bordas não indiretas, mas você pode consultar bordas em qualquer direção usando -[:label]- a sintaxe.

Filtrar padrões com WHERE integrado

Coloque WHERE dentro do padrão quando uma condição definir qual nó ou aresta pode participar da correspondência. Use uma condição MATCH ... WHERE no nível da instrução para filtrar posteriormente a correspondência concluída, ou um FILTER separado quando a condição se aplica à linha produzida por uma instrução anterior. A colocação de predicados pode alterar os resultados do caminho mais curto. Para mais informações, veja Colocar predicados antes ou depois da seleção de caminhos.

Por exemplo, para encontrar pessoas nascidas antes de 1990 que trabalham em uma empresa cujo nome começa com '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 as propriedades de borda para restringir quais relações correspondem. Por exemplo, para retornar somente as pessoas que começaram a trabalhar em uma empresa em 2010 ou depois:

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

Corresponder relações de vários saltos

Use padrões de comprimento variável para percorrer vários saltos em uma expressão. Especifique o número mínimo e máximo de saltos com a sintaxe {min,max}.

Por exemplo, para encontrar até 100 pessoas acessíveis dentro de dois a quatro graus de amizade de Alice:

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

Para encontrar até 100 conexões imediatas e de segundo grau (um ou dois saltos) de Alice:

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

Controle de travessia com modos de caminho

Por padrão, o GQL usa WALK, que permite nós e arestas repetidos. Use outro modo de caminho quando precisar de uma unicidade mais rigorosa dos elementos.

Modo de percurso Behavior Use quando…
WALK Permite repetição de nós e arestas (padrão) Você quer todos os percursos correspondentes dentro de um limite finito.
TRAIL Sem arestas repetidas Você quer evitar percorrer novamente a mesma aresta, mas o mesmo nó pode ser alcançado por arestas diferentes.
SIMPLE Não há nós repetidos, exceto um nó inicial e final compartilhado, nem arestas repetidas Você deseja que nenhum nó apareça mais de uma vez no meio de um caminho, mas permita caminhos que se fechem de volta ao início. Útil para detectar loops.
ACYCLIC Sem nós ou arestas repetidas Você precisa garantir que nenhum dos nós apareça no caminho mais de uma vez. O uso para hierarquias estritas, linhagem ou qualquer passagem em que revisitar um nó produziria resultados incorretos.

WALK é o modo mais permissivo e ACYCLIC é o mais restritivo.

Para SIMPLE e ACYCLIC, a unicidade das arestas decorre da unicidade do nó. Um SIMPLE caminho pode se fechar ao retornar ao seu primeiro nó, mas ainda assim não pode reutilizar uma aresta.

Para ilustrar a diferença, considere o percurso Alice → Bob → Carol → Bob:

  • WALK – permite esse caminho. Nodos e arestas podem ser repetidos livremente.
  • TRAIL – permite esse caminho. Bob aparece duas vezes, mas cada borda usada é uma relação diferente (Alice→Bob e Carol→Bob são bordas distintas), portanto, nenhuma borda é repetida.
  • SIMPLE – bloqueia esse caminho. Bob aparece mais de uma vez, e "SIMPLE" só permite que um nó se repita se esse mesmo nó for o início e o fim do caminho (um ciclo fechado). Aqui alice é o início e Bob é o fim, então nenhuma exceção se aplica.
  • ACYCLIC – bloqueia esse caminho. Bob aparece mais de uma vez em qualquer lugar no caminho.

O exemplo a seguir mostra como usar TRAIL para contar quantos caminhos distintos levam a cada uma das 100 primeiras pessoas acessíveis na rede de Alice em quatro 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

Utilize ACYCLIC para retornar até 100 pessoas alcançáveis a partir de Alice dentro de quatro saltos, onde cada pessoa no caminho é única.

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

O modo de correspondência padrão REPEATABLE ELEMENTS permite que uma aresta seja reutilizada por caminhos separados no mesmo padrão de gráfico. Use DIFFERENT EDGES ou DIFFERENT RELATIONSHIPS quando cada vínculo de aresta ao longo de todos os caminhos precisar ser diferente:

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

Retorne um dos caminhos mais curtos

ALL é a busca de caminho padrão e retorna todos os caminhos correspondentes. Use ANY SHORTEST para retornar um caminho mais curto para cada par fonte-destino. A consulta a seguir encontra um caminho mais curto de Alice até 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

Quando vários caminhos mais curtos empatam, qual caminho é retornado não é determinístico. ALL SHORTEST e ANY buscas por caminho não são suportadas.

A colocação de predicados pode alterar o resultado de ANY SHORTEST. Predicados embutidos de nós e arestas restringem quais caminhos podem ser considerados, enquanto um pós-filtro pode remover o caminho selecionado sem, em vez disso, escolher um caminho mais longo. Veja Colocar predicados antes ou depois da seleção de caminhos.

Dica

Prefiro um limite superior finito para custo de consulta previsível. Padrões ilimitados ALL WALK não são suportados. Padrões ilimitados com TRAIL, SIMPLE, ou ACYCLIC terminam por unicidade de elemento, mas ainda podem retornar muitos caminhos. O Unbounded ANY SHORTEST WALK suporta apenas formas específicas de consulta. Confira as limitações atuais.

Usar a reutilização de variável para expressar entidades compartilhadas

Reutilização da mesma variável em duas partes de um padrão cria uma restrição de igualdade implícita – ambas as referências devem corresponder ao mesmo nó. Essa técnica permite que você expresse "localizar entidades conectadas por meio de uma terceira entidade compartilhada".

Por exemplo, para encontrar até 100 pares de pessoas que se conhecem e trabalham na mesma empresa:

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

A variável c é reutilizada para ambos os workAt alvos, portanto, a consulta retorna apenas pares em que ambas as pessoas se conhecem e trabalham na mesma empresa.

Para encontrar até 100 pares de pessoas que gostaram do mesmo post:

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

Dica

A WHERE a.id < b.id condição impede que pares duplicados (Alice + Bob e Bob + Alice) apareçam nos resultados.

Combinar vários padrões

Listar vários padrões em um único MATCH, separados por vírgulas. Reutilize uma variável quando os padrões precisam vincular o mesmo elemento do grafo.

Por exemplo, para encontrar até 100 pessoas, juntamente com seu local de trabalho e a cidade em que vivem:

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

A variável p compartilhada conecta os dois padrões. Cada linha de resultado representa uma pessoa com sua empresa e cidade.

Padrões desconectados também são válidos, mas formam um produto cartesiano de suas correspondências. Use apenas quando você precisar intencionalmente de todas as combinações. Para orientações sobre desempenho, consulte Use variáveis compartilhadas para junções eficientes.

Associar relações opcionais

Use OPTIONAL MATCH quando uma relação pode não existir para cada nó. As linhas sem correspondência são retidas com NULL valores, semelhantes a um SQL LEFT JOIN.

Por exemplo, retorne até 100 pessoas com o nome da empresa, incluindo pessoas sem empregador (ou seja, que retornam NULL para a coluna da empresa):

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

Use IS NULL depois OPTIONAL MATCH para encontrar até 100 pessoas que não trabalham em nenhuma empresa:

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