Quais são os cenários comuns para usar a semântica de grafo KQL (Kusto Query Language)?
A semântica de grafo em Kusto Query Language (KQL) permite modelar e consultar dados como gráficos. Há muitos cenários em que os gráficos são úteis para representar dados complexos e dinâmicos que envolvem relacionamentos muitos-para-muitos, hierárquicos ou em rede, como redes sociais, sistemas de recomendação, ativos conectados ou gráficos de conhecimento.
Neste artigo, você aprenderá sobre os seguintes cenários comuns para usar a semântica de grafo KQL:
Amigos de um amigo
Um caso de uso comum para gráficos é modelar e consultar redes sociais, onde os nós são usuários e as bordas são amizades ou interações. Por exemplo, imagine que temos uma tabela chamada Usuários que tem dados sobre usuários, como nome e organização, e uma tabela chamada Sabe que tem dados sobre as amizades entre usuários, conforme mostrado no diagrama a seguir:
Sem usar a semântica de grafo no KQL, você pode criar um grafo para encontrar amigos de um amigo usando várias junções, da seguinte maneira:
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
Você pode usar a semântica de grafo no KQL para executar a mesma consulta de maneira mais intuitiva e eficiente. A consulta a seguir usa o operador make-graph para criar um grafo direcionado de FirstUser para SecondUser e enriquece as propriedades nos nós com as colunas fornecidas pela tabela Users . Depois que o gráfico é instanciado, o operador de correspondência de gráfico fornece o padrão de amigo de um amigo, incluindo filtros e uma projeção que resulta em uma 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
Insights de dados de log
Em alguns casos de uso, você deseja obter insights de uma tabela simples e simples contendo informações de séries temporais, como dados de log. Os dados em cada linha são uma cadeia de caracteres que contém dados brutos. Para criar um gráfico a partir desses dados, você deve primeiro identificar as entidades e relacionamentos relevantes para a análise do gráfico. Por exemplo, suponha que você tenha uma tabela chamada rawLogs de um servidor Web que contém informações sobre solicitações, como o carimbo de data/hora, o endereço IP de origem, o recurso de destino e muito mais.
A tabela a seguir mostra um exemplo dos dados brutos:
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 maneira possível de modelar um gráfico a partir dessa tabela é tratar os endereços IP de origem como nós e as solicitações da Web para recursos como bordas. Você pode usar o operador de análise para extrair as colunas necessárias para o gráfico e, em seguida, criar um gráfico que represente o tráfego de rede e as interações entre diferentes origens e destinos. Para criar o gráfico, você pode usar o operador make-graph especificando as colunas de origem e destino como os pontos de extremidade de borda e, opcionalmente, fornecendo colunas adicionais como propriedades de borda ou nó.
A consulta a seguir cria um gráfico a partir dos logs brutos:
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;
Essa consulta analisa os logs brutos e cria um grafo direcionado em que os nós são endereços IP ou recursos e cada borda é uma solicitação da origem para o destino, com o carimbo de data/hora e o verbo HTTP como propriedades de borda.
Depois que o gráfico é criado, você pode usar o operador de correspondência de gráfico para consultar os dados do gráfico usando padrões, filtros e projeções. Por exemplo, você pode criar um padrão que faz uma recomendação simples com base nos recursos que outros endereços IP solicitaram nos últimos cinco minutos, da seguinte maneira:
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 |
---|
/produto/42 |
A consulta retorna "/product/42" como uma recomendação com base em um log baseado em texto bruto.