Partilhar via


Quais são os cenários comuns para utilizar a semântica de grafo (Pré-visualização) do Linguagem de Pesquisa Kusto (KQL)?

Aviso

Esta funcionalidade está atualmente em pré-visualização e pode estar sujeita a alterações. A semântica e a sintaxe da funcionalidade do gráfico podem ser alteradas antes de serem lançadas como geralmente disponíveis.

A semântica de grafos no Linguagem de Pesquisa Kusto (KQL) permite-lhe modelar e consultar dados como gráficos. Existem muitos cenários em que os gráficos são úteis para representar dados complexos e dinâmicos que envolvem relações muitos-para-muitos, hierárquicas ou em rede, como redes sociais, sistemas de recomendação, recursos ligados ou gráficos de conhecimento.

Neste artigo, ficará a saber mais sobre os seguintes cenários comuns para utilizar a semântica de grafos KQL:

Amigos de um amigo

Um caso de utilização comum para gráficos é modelar e consultar redes sociais, onde os nós são utilizadores e as arestas são amizades ou interações. Por exemplo, imagine que temos uma tabela denominada Utilizadores que tem dados sobre utilizadores, como o respetivo nome e organização, e uma tabela denominada Sabe que tem dados sobre as amizades entre utilizadores, conforme mostrado no diagrama seguinte:

Diagrama que mostra um gráfico de amigos de um amigo.

Sem utilizar a semântica de grafos na KQL, pode criar um gráfico para encontrar amigos de um amigo através de múltiplas associações, da seguinte forma:

let Users = datatable (UserId: string, name: string, org: string)[]; // nodes
let Knows = datatable (FirstUser: string, SecondUser: string)[]; // edges
Users
| where org == "Contoso"
| join kind=inner (Knows) on $left.UserId == $right.FirstUser
| join kind=innerunique(Users) on $left.SecondUser == $right.UserId
| join kind=inner (Knows) on $left.SecondUser == $right.FirstUser
| join kind=innerunique(Users) on $left.SecondUser1 == $right.UserId
| where UserId != UserId1
| project name, name1, name2

Pode utilizar a semântica de grafos na KQL para efetuar a mesma consulta de uma forma mais intuitiva e eficiente. A consulta seguinte utiliza o operador make-graph para criar um gráfico direcionado de FirstUser para SecondUser e enriquece as propriedades nos nós com as colunas fornecidas pela tabela Utilizadores . Assim que o gráfico é instanciado, o operador de correspondência de grafos fornece o padrão friend-of-a-friend, incluindo filtros e uma projeção que resulta numa saída tabular.

let Users = datatable (UserId:string , name:string , org:string)[]; // nodes
let Knows = datatable (FirstUser:string , SecondUser:string)[]; // edges
Knows
| make-graph FirstUser --> SecondUser with Users on UserId
| graph-match (user)-->(middle_man)-->(friendOfAFriend)
    where user.org == "Contoso" and user.UserId != friendOfAFriend.UserId
    project contoso_person = user.name, middle_man = middle_man.name, kusto_friend_of_friend = friendOfAFriend.name

Informações dos dados de registo

Em alguns casos de utilização, quer obter informações de uma tabela simples que contém informações de série temporal, como dados de registo. Os dados em cada linha são uma cadeia que contém dados não processados. Para criar um gráfico a partir destes dados, primeiro tem de identificar as entidades e as relações que são relevantes para a análise de gráficos. Por exemplo, suponha que tem uma tabela chamada rawLogs de um servidor Web que contém informações sobre pedidos, como o carimbo de data/hora, o endereço IP de origem, o recurso de destino e muito mais.

A tabela seguinte mostra um exemplo dos dados não processados:

let rawLogs = datatable (rawLog: string) [
    "31.56.96.51 - - [2019-01-22 03:54:16 +0330] \"GET /product/27 HTTP/1.1\" 200 5379 \"https://www.contoso.com/m/filter/b113\" \"some client\" \"-\"",
    "31.56.96.51 - - [2019-01-22 03:55:17 +0330] \"GET /product/42 HTTP/1.1\" 200 5667 \"https://www.contoso.com/m/filter/b113\" \"some client\" \"-\"",
    "54.36.149.41 - - [2019-01-22 03:56:14 +0330] \"GET /product/27 HTTP/1.1\" 200 30577 \"-\" \"some client\" \"-\""
];

Uma forma possível de modelar um gráfico desta tabela é tratar os endereços IP de origem como nós e os pedidos Web para recursos como arestas. Pode utilizar o operador de análise para extrair as colunas de que precisa para o gráfico e, em seguida, pode criar um gráfico que representa o tráfego de rede e as interações entre diferentes origens e destinos. Para criar o gráfico, pode utilizar o operador make-graph que especifica as colunas de origem e de destino como pontos finais periféricos e, opcionalmente, fornecer colunas adicionais como propriedades de limite ou nó.

A consulta seguinte cria um gráfico a partir dos registos não processados:

let parsedLogs = rawLogs
    | parse rawLog with ipAddress: string " - - [" timestamp: datetime "] \"" httpVerb: string " " resource: string " " *
    | project-away rawLog;
let edges = parsedLogs;
let nodes =
    union
        (parsedLogs
        | distinct ipAddress
        | project nodeId = ipAddress, label = "IP address"),
        (parsedLogs | distinct resource | project nodeId = resource, label = "resource");
let graph = edges
    | make-graph ipAddress --> resource with nodes on nodeId;

Esta consulta analisa os registos não processados e cria um gráfico direcionado onde os nós são endereços IP ou recursos e cada aresta é um pedido da origem para o destino, com o carimbo de data/hora e o verbo HTTP como propriedades de limite.

Diagrama que mostra um gráfico dos dados de registo analisados.

Assim que o gráfico for criado, pode utilizar o operador de correspondência de grafos para consultar os dados do grafo através de padrões, filtros e projeções. Por exemplo, pode criar um padrão que faz uma recomendação simples com base nos recursos que outros endereços IP pediram nos últimos cinco minutos, da seguinte forma:

graph
| graph-match (startIp)-[request]->(resource)<--(otherIP)-[otherRequest]->(otherResource)
    where startIp.label == "IP address" and //start with an IP address
    resource.nodeId != otherResource.nodeId and //recommending a different resource
    startIp.nodeId != otherIP.nodeId and //only other IP addresses are interesting
    (request.timestamp - otherRequest.timestamp < 5m) //filter on recommendations based on the last 5 minutes
    project Recommendation=otherResource.nodeId

Saída

Recomendação
/product/42

A consulta devolve "/product/42" como uma recomendação com base num registo não processado baseado em texto.