Padrões de grafo GQL

Os padrões de grafo são os principais blocos de construção de suas consultas GQL no graph no Microsoft Fabric. Eles descrevem as estruturas que você está procurando no grafo usando nós e bordas de maneira intuitiva e visual. Pense em padrões de grafo como modelos que o mecanismo de consulta tenta corresponder aos dados reais em seu grafo.

Este artigo explica as regras de sintaxe e de composição para padrões de grafo no GQL.

Importante

Este artigo utiliza exclusivamente o conjunto de dados de exemplos de grafos de redes sociais.

Padrões de elemento simples

Padrões de elemento simples ajudam você a corresponder nós individuais e bordas do grafo que atendem a requisitos específicos. Esses padrões formam a base para correspondência de padrões mais complexa.

Padrões de nó simples

Um padrão de nó especifica os rótulos e as propriedades que um nó deve ter que corresponder:

(:Place&City { name: "New York" })

Esse padrão corresponde a todos os nós que têm rótulos e Place rótulos City (indicados & pelo operador) e cuja name propriedade é "New York"igual a . Essa combinação de rótulos e propriedades necessários é chamada de preenchimento do padrão de nó.

Principais conceitos:

  • Correspondência de rótulos: use & para exigir vários rótulos.
  • Filtragem de propriedade: especifique os valores exatos que as propriedades devem corresponder.
  • Correspondência flexível ("covariante").: os nós correspondentes podem ter mais rótulos e propriedades além dos especificados.

Observação

Os nós podem ter vários rótulos, mas ainda não há suporte para tipos de borda com vários rótulos.

Padrões de borda simples

Os padrões de borda são mais complexos do que os padrões de nó. Eles não apenas especificam um filler, mas também conectam um padrão de nó de origem a um padrão de nó alvo. Os padrões de borda descrevem os requisitos na borda e em seus pontos de extremidade:

(:Person)-[:likes|knows { creationDate: ZONED_DATETIME("2010-08-31T13:16:54Z") }]->(:Comment)

A direção -[...]-> da seta é importante — ela (:Person) determina como o padrão do nó de origem e (:Comment) como o padrão do nó de destino. Entender a direção da borda é crucial para consultar o grafo corretamente.

Padrão espelhado equivalente:

Você pode inverter a seta e trocar os padrões de nó para criar o padrão de borda espelhado equivalente:

(:Comment)<-[:likes { creationDate: ZONED_DATETIME("2010-08-31T13:16:54Z") }]-(:Person)

Esse padrão encontra as mesmas relações, mas da perspectiva oposta.

Padrões de borda direcionados a qualquer

Quando a direção de uma borda de grafo não importa para sua consulta, você pode deixá-la não especificada criando um padrão de borda direcionado:

(:Song)-[:inspired]-(:Movie)

Esse padrão corresponde às mesmas arestas que (:Song)-[:inspired]->(:Movie) e (:Movie)-[:inspired]->(:Song) combinado, independentemente de qual nó é a origem e qual é o alvo (este exemplo não é do tipo grafo de rede social).

Atalhos de padrão de borda do grafo

O GQL fornece atalhos convenientes para padrões de borda comuns para tornar suas consultas mais concisas:

  • ()->() ()-[]->() significa (borda direcionada com qualquer rótulo)
  • ()<-() ()<-[]-() significa (borda direcionada ao contrário com qualquer rótulo)
  • ()-() ()-[]-() significa (qualquer borda direcionada com qualquer rótulo)

Esses atalhos podem ser úteis quando você se preocupa com a conectividade, mas não com o tipo de borda de grafo específico.

Expressões de rótulo

Os padrões podem expressar requisitos complexos nos rótulos de nós e bordas correspondentes.

Example:

MATCH (:Person|(Organization&!Company))-[:isLocatedIn]->(p:City|Country)
RETURN count(*) AS num_matches

Isso conta o número de isLocatedIn bordas que conectam Person nós ou Organizationnós (mas não)Company (que são sempre University nós no esquema de rede social) ou CityCountry nós.

Sintaxe:

Sintaxe Meaning
A&B Os rótulos precisam incluir A e B.
A|B Os rótulos precisam incluir pelo menos um de A ou B.
!A Os rótulos precisam excluir A.

Além disso, use parênteses para controlar a ordem da avaliação da expressão de rótulo. Por padrão, ! tem a precedência mais alta e & tem precedência maior que |. Portanto, !A&B|C|!D é o mesmo que ((!A)&B)|C|(!D).

Variáveis de associação

As variáveis permitem que você se refira a elementos de grafo correspondentes em outras partes da consulta. Entender como associar e usar variáveis é essencial para criar consultas avançadas.

Variáveis de elemento de associação

Os padrões de nó e de borda podem associar nós e bordas correspondentes a variáveis para referência posterior.

(p:Person)-[w:workAt]->(c:Company)

Nesse padrão, p é associado a nós correspondentes Person , w a bordas correspondentes workAt e c a nós correspondentes Company .

Reutilização de variável para restrições estruturais:

Reutilização da mesma variável em um padrão várias vezes expressa uma restrição na estrutura de correspondências. Cada ocorrência da mesma variável deve sempre se associar ao mesmo elemento de grafo em uma correspondência válida. A reutilização de variável é eficiente para expressar requisitos estruturais complexos.

(c:Company)<-[:workAt]-(x:Person)-[:knows]-(y:Person)-[:workAt]->(c:Company)

O padrão localiza nós e que se conhecem e funcionam no mesmoPerson, que está associado à variávelx.yCompanyc A reutilização garante c que ambas as pessoas trabalhem na mesma empresa.

Predicados de padrão com variáveis de elemento:

As variáveis de elemento de associação permitem que você especifique predicados de padrão de borda e nó. Em vez de apenas fornecer um preenchimento com valores de propriedade exatos como { name: "New York, USA" }, um preenchimento pode especificar um predicado que é avaliado para cada elemento candidato. O padrão só corresponde se o predicado for avaliado como TRUE:

(p:Person)-[e:knows WHERE e.creationDate >= ZONED_DATETIME("2000-01-01T18:00:00Z")]-(o:Person)

O padrão de borda encontra pessoas que se conheciam desde 1º de janeiro de 2000, usando uma condição flexível em vez de uma correspondência exata.

Observação

As variáveis de padrão de borda sempre se associam à borda individual no predicado de padrão de borda, mesmo ao usar padrões de comprimento variável. Isso pode ajudar com a não necessidade de remover as variáveis de lista de grupos de borda para executar um pós-filtro. Consulte variáveis de borda de padrão de comprimento variável Bind.

Técnicas avançadas de predicado de padrão:

Predicados de padrão fornecem recursos avançados de filtragem embutida que podem melhorar a legibilidade da consulta:

-- Multiple conditions in node predicates
MATCH (p:Person WHERE p.birthday < 19900101 AND p.gender = 'female')
      -[:workAt]->
      (c:Company WHERE c.name STARTS WITH 'A')

-- Filter on an edge property
MATCH (p1:Person)-[w:workAt WHERE w.workFrom >= 2010]->(c:Company)

-- MATCH WHERE: evaluated after pattern matching
MATCH (p:Person)-[:workAt]->(c:Company)
WHERE p.browserUsed = 'Firefox' AND c.name IS NOT NULL

-- Filter during matching and after
MATCH (p:Person WHERE p.gender = 'male')-[:workAt]->(c:Company)
WHERE p.birthday < 19900101 AND c.url IS NOT NULL

Dica

Mantenha um predicado dentro do padrão quando ele descreve qual nó ou aresta pode participar da partida.

Variáveis de caminho de associação

Você também pode associar um caminho correspondente a uma variável de caminho para processamento adicional ou para retornar a estrutura de caminho completa ao usuário:

p=(c:Company)<-[:workAt]-(x:Person)-[:knows]-(y:Person)-[:workAt]->(c:Company)

Aqui, p está associado a um valor de caminho que representa a estrutura de caminho correspondente completa, incluindo valores de referência para todos os nós e bordas na ordem fornecida.

Caminhos limitados podem ser retornados ao usuário ou processados posteriormente usando funções como NODES ou EDGES:

MATCH p=(c:Company)<-[:workAt]-(x:Person)-[:knows]-(y:Person)-[:workAt]->(c:Company)
LET path_edges = edges(p)
RETURN path_edges, size(path_edges) AS num_edges
GROUP BY path_edges

Compor padrões

Consultas do mundo real geralmente exigem padrões mais complexos do que estruturas simples de nó-borda-nó. A GQL fornece várias maneiras de compor padrões para passagens de grafo sofisticadas.

Compor padrões de caminho

Os padrões de caminho podem ser compostos concatenando padrões simples de nó e borda para criar passagens mais longas.

(:Person)-[:knows]->(:Person)-[:workAt]->(:Company)-[:isLocatedIn]->(:Country)-[:isPartOf]->(:Continent)

O padrão percorre de uma pessoa através de suas conexões sociais e profissionais para encontrar onde a empresa de seu colega está localizada.

Construção de padrão em forma de peça: Você também pode criar padrões de caminho de forma mais incremental, o que pode facilitar a leitura e a compreensão de padrões complexos:

(:Person)-[:knows]->(p:Person),
(p:Person)-[:workAt]->(c:Company),
(c:Company)-[:isLocatedIn]->(:Country)-[:isPartOf]->(:Continent)

Essa abordagem divide a mesma passagem em etapas lógicas, facilitando a compreensão e a depuração.

Compor padrões não lineares

A forma resultante de um padrão não precisa ser um caminho linear. Você pode corresponder a estruturas mais complexas, como padrões em forma de estrela, que radiam de um nó central:

(p:Person),
(p)-[:studyAt]->(u:University),
(p)-[:workAt]->(c:Company),
(p)-[:likes]-(m)

O padrão localiza uma pessoa junto com suas preferências de educação, emprego e conteúdo de uma só vez, uma consulta de perfil abrangente.

Padrões no mesmo MATCH não precisam compartilhar uma variável. Padrões desconectados formam um produto cartesiano de suas correspondências. Reutilize uma variável quando os padrões devem vincular o mesmo elemento do grafo e só as combinações unidas devem permanecer.

Reutilização dos elementos de controle

O GQL controla nós e arestas repetidos em dois níveis:

  • Um modo de correspondência se aplica ao padrão completo do grafo, incluindo caminhos separados por vírgulas.
  • Um modo caminho se aplica a um caminho.

O modo de partida padrão é REPEATABLE ELEMENTS. Ela permite que a mesma ligação de elementos ocorra em diferentes partes do padrão do grafo, sujeita ao modo caminho de cada caminho. Você pode escrevê-lo explicitamente:

REPEATABLE ELEMENTS (a)-[e1:knows]->(b), (a)-[e2:knows]->(c)

Use DIFFERENT EDGES ou seu sinônimo DIFFERENT RELATIONSHIPS para exigir singularidade de aresta em todo o padrão do grafo. Esse modo de combinação também transforma qualquer WALK caminho no padrão em comportamento TRAIL .

DIFFERENT EDGES (a)-[e1:knows]->(b), (a)-[e2:knows]->(c)

Os seguintes modos de caminho controlam elementos repetidos dentro de cada caminho:

Modo de percurso Reutilização de elementos
WALK Nós e arestas podem se repetir.
TRAIL Arestas não podem se repetir, mas nós podem repetir.
SIMPLE Nós não podem repetir, exceto que o primeiro e o último nó podem ser iguais. As bordas não podem se repetir.
ACYCLIC Nós não podem se repetir, incluindo o primeiro e o último nó. As bordas não podem se repetir.

WALK é o modo de caminho padrão. Prefixe um caminho com outro modo quando você precisa de uma unicidade de elemento mais estrita:

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

TRAIL (a)-[e1:knows]->(b)-[e2:knows]->(c)-[e3:knows]->(d)

O TRAIL padrão produz apenas correspondências em que e1, e2, e e3 são diferentes. Nós ainda podem repetir, então o caminho pode formar um ciclo sem reutilizar uma aresta.

Controle quais caminhos são retornados

Um prefixo de busca de caminho controla quais caminhos um padrão de caminho retorna. O prefixo padrão ALL retorna todos os caminhos que correspondem ao modo e padrão do caminho. Você pode escrever ALL explicitamente:

ALL TRAIL (a:Person)-[:knows]->{1,4}(b:Person)

Use ANY SHORTEST para retornar o caminho correspondente mais curto para cada par fonte-destino de cada linha de entrada:

MATCH p = ANY SHORTEST
  (src:Person)-[:knows]->{1,4}(dst:Person)
RETURN src.id AS sourceId, dst.id AS targetId, path_length(p) AS hopCount
ORDER BY sourceId, targetId
LIMIT 100

Se múltiplos caminhos empatam pelo menor comprimento, a consulta retorna um deles, mas qual caminho ligado é retornado não é determinístico. Um limite inferior zero pode retornar um caminho de zero salto de um nó de origem para si mesmo.

ALL SHORTEST e ANY buscas por caminho não são suportadas.

Coloque predicados antes ou depois da seleção de caminhos

A colocação de predicados determina se uma condição define caminhos elegíveis ou se filtra caminhos após o prefixo de busca de caminho selecioná-los:

  • Um inline WHERE em um padrão de nó ou aresta faz parte do padrão. Ele limita quais caminhos são elegíveis antes ALL ou ANY SHORTEST aplicados.
  • Um nível WHERE de instrução após o padrão completo MATCH é um filtro de pós-texto. Ele filtra as linhas depois que o prefixo de busca de caminho já foi selecionado.
  • Uma instrução subsequente FILTER também filtra linhas após a seleção do caminho.

Essa distinção é especialmente importante com ANY SHORTEST. No padrão a seguir, apenas knows as arestas criadas na data especificada ou após ela são elegíveis quando a consulta seleciona o caminho mais curto:

MATCH p = ANY SHORTEST
  (src:Person WHERE src.firstName = 'Alice')
  -[connection:knows
    WHERE connection.creationDate >= ZONED_DATETIME('2020-01-01T00:00:00Z')]->{1,4}
  (dst:Person WHERE dst.firstName = 'Bob')
RETURN p

Mover a condição da borda para um filtro de pós-filtro muda o significado. A consulta primeiro seleciona o caminho mais curto sem essa condição. Ele então remove o caminho selecionado se qualquer aresta falhar na condição; ele não seleciona um caminho mais longo, em vez disso:

MATCH p = ANY SHORTEST
  (src:Person WHERE src.firstName = 'Alice')
  -[connections:knows]->{1,4}
  (dst:Person WHERE dst.firstName = 'Bob')
FILTER ALL(connection IN connections
           WHERE connection.creationDate >= ZONED_DATETIME('2020-01-01T00:00:00Z'))
RETURN p

Importante

Para algumas ANY SHORTEST formas de consulta, o Graph pode atualmente aplicar uma condição em nível MATCH ... WHERE de instrução antes da seleção do caminho. Até que essa limitação seja resolvida, use predicados inline para elegibilidade de caminho e uma instrução separada FILTER para filtragem pós-seleção. Para obter mais informações, confira Limitações atuais.

Usar padrões de comprimento variável

Padrões de comprimento variável são construções poderosas que permitem encontrar caminhos de comprimentos variados sem escrever especificações de padrão repetitivo. Eles são essenciais para percorrer hierarquias, redes sociais e outras estruturas em que o comprimento ideal do caminho não é conhecido com antecedência.

Padrões de comprimento variável limitados

Muitas consultas de grafo comuns exigem repetir o mesmo padrão de borda várias vezes. Em vez de escrever padrões detalhados como:

(:Person)-[:knows]->(:Person)-[:knows]->(:Person)-[:knows]->(:Person)

Você pode usar a sintaxe de comprimento variável mais concisa:

(:Person)-[:knows]->{3}(:Person)

Especifica {3} que o padrão de -[:knows]-> borda deve ser repetido exatamente três vezes.

Intervalos de repetição flexíveis: Para obter mais flexibilidade, você pode especificar um limite inferior e um limite superior para a repetição:

(:Person)-[:knows]->{1, 3}(:Person)

Esse padrão encontra amigos diretos, amigos de amigos e amigos de amigos de amigos em uma única consulta.

Observação

O limite inferior também pode ser zero. Uma correspondência zero-hop não contém arestas e exige que ambos os padrões de nós finais coincidam com o mesmo nó.

Exemplo:

(p1:Person)-[:knows]->{0,1}(p2:Person)

Esse padrão corresponde a cada pessoa tanto p1 como quanto p2 a zero saltos, e corresponde a pares conectados em um único salto.

Quando nenhum limite inferior é especificado em {,n}, ele passa a zero por padrão.

Composições complexas de comprimento variável: Padrões de comprimento variável podem fazer parte de padrões maiores e mais complexos, como na consulta a seguir:

MATCH (c1:Comment)<-[:likes]-(p1:Person)-[:knows]-(p2:Person)-[:likes]->(c2:Comment),
      (c1:Comment)<-[:replyOf]-{1,3}(m)-[:replyOf]->{1,3}(c2:Comment)
RETURN *
LIMIT 100

O padrão encontra pares de comentários onde pessoas que se conhecem curtiram comentários diferentes e uma mensagem m é conectada a cada comentário por uma cadeia de uma a três replyOf arestas.

Associar variáveis de borda de padrão de comprimento variável

Quando você associa um padrão de borda de comprimento variável, o valor e o tipo da variável de borda mudam dependendo do contexto de referência. Entender esse comportamento é crucial para processar corretamente correspondências de comprimento variável:

Dois graus de referência:

  • Dentro de um padrão de comprimento variável: variáveis de borda do grafo se associam a cada borda individual ao longo do caminho correspondente (também chamado de "grau singleton de referência")
  • Fora de um padrão de comprimento variável: as variáveis de borda do grafo se associam à sequência de todas as bordas ao longo do caminho correspondente (também chamado de "grau de referência do grupo")

Exemplo demonstrando ambos os contextos:

MATCH (:Person)-[e:knows WHERE e.creationDate >= ZONED_DATETIME("2000-01-01T00:00:00Z")]->{1,3}()
RETURN e[0]
LIMIT 100

A avaliação da variável e de borda ocorre em dois contextos:

  • MATCH Na declaração: A consulta encontra cadeias de amigos-de-amigos-de-amigos onde cada amizade foi estabelecida desde o ano 2000. Durante a correspondência de padrões, o predicado e.creationDate >= ZONED_DATETIME("2000-01-01T00:00:00Z") de padrão de borda é avaliado uma vez para cada borda candidata. Nesse contexto, e está associado a um único valor de referência de borda.

  • Na instruçãoRETURN: aqui, e está associada a uma lista (grupo) de valores de referência de borda na ordem em que eles ocorrem na cadeia correspondente. O resultado é o primeiro valor de referência de e[0] borda em cada cadeia correspondente.

Variáveis de padrão de comprimento variável nas arestas em agregação horizontal:

Variáveis de aresta limitadas por correspondência de padrões de comprimento variável são listas de grupos fora do padrão de comprimento variável e, portanto, podem ser usadas em agregação horizontal.

MATCH (a:Person)-[e:knows WHERE e.creationDate >= ZONED_DATETIME("2000-01-01T00:00:00Z")]->{1,3}(b)
RETURN a, b, size(e) AS num_edges
LIMIT 100

Para mais informações, veja Funções agregadas.

Padrões de comprimento variável não associados

Use um quantificador ilimitado quando o comprimento máximo do caminho não for conhecido:

-- Two or more edges
TRAIL (:Person)-[:knows]->{2,}(:Person)

Os * atalhos e + especificam zero ou mais repetições e uma ou mais repetições:

-- Zero or more edges
ACYCLIC (:Person)-[:knows]->*(:Person)

-- One or more edges
SIMPLE (:Person)-[:knows]->+(:Person)

Um padrão ilimitado com a combinação padrão ALL WALK é rejeitado porque ciclos podem produzir infinitos caminhos correspondentes. Use TRAIL, SIMPLE, ou ACYCLIC para limitar o caminho através da unicidade de aresta ou nó. Esses modos garantem terminação, mas um grafo grande ainda pode produzir um grande número de caminhos.

Importante

Para um caminho limitado por um ilimitado ANY SHORTEST WALK, os únicos usos suportados são PATH_LENGTH(path) e, junto com ele, path IS NULL. O grafo não materializa o caminho completo nessa forma. Use um limite superior finito ou especifique TRAIL, SIMPLE, ou ACYCLIC para retornar ou usar o caminho de outra forma.