Quels sont les scénarios courants d’utilisation de la sémantique de graphe Langage de requête Kusto (KQL) ?
La sémantique des graphiques dans Langage de requête Kusto (KQL) vous permet de modéliser et d’interroger des données sous forme de graphiques. Il existe de nombreux scénarios où les graphiques sont utiles pour représenter des données complexes et dynamiques qui impliquent des relations plusieurs-à-plusieurs, hiérarchiques ou réseau, telles que des réseaux sociaux, des systèmes de recommandation, des ressources connectées ou des graphiques de connaissances.
Dans cet article, vous allez découvrir les scénarios courants suivants pour utiliser la sémantique de graphe KQL :
Amis d’un ami
Un cas d’usage courant pour les graphiques consiste à modéliser et interroger des réseaux sociaux, où les nœuds sont des utilisateurs et des arêtes sont des amitiés ou des interactions. Par exemple, imaginez que nous avons une table appelée Utilisateurs qui a des données sur les utilisateurs, telles que leur nom et leur organisation, et une table appelée Sait qui contient des données sur les amitiés entre les utilisateurs, comme illustré dans le diagramme suivant :
Sans utiliser la sémantique de graphe dans KQL, vous pouvez créer un graphique pour rechercher des amis d’un ami à l’aide de plusieurs jointures, comme suit :
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
Vous pouvez utiliser la sémantique de graphe dans KQL pour effectuer la même requête de manière plus intuitive et plus efficace. La requête suivante utilise l’opérateur make-graph pour créer un graphique dirigé de FirstUser vers SecondUser et enrichit les propriétés sur les nœuds avec les colonnes fournies par la table Users. Une fois le graphique instancié, l’opérateur de correspondance de graphique fournit le modèle friend-of-a-friend, y compris les filtres et une projection qui entraîne une sortie tabulaire.
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
Recommandations à partir des données de journal
Dans certains cas d’usage, vous souhaitez obtenir des insights à partir d’une table plate simple contenant des informations de série chronologique, telles que les données de journal. Les données de chaque ligne sont une chaîne qui contient des données brutes. Pour créer un graphique à partir de ces données, vous devez d’abord identifier les entités et relations pertinentes pour l’analyse du graphique. Par exemple, supposons que vous ayez une table appelée rawLogs à partir d’un serveur web qui contient des informations sur les requêtes, telles que l’horodatage, l’adresse IP source, la ressource de destination, et bien plus encore.
Le tableau suivant montre un exemple de données brutes :
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\" \"-\""
];
Une façon possible de modéliser un graphique à partir de cette table consiste à traiter les adresses IP sources en tant que nœuds et les requêtes web aux ressources comme des arêtes. Vous pouvez utiliser l’opérateur d’analyse pour extraire les colonnes dont vous avez besoin pour le graphique, puis créer un graphique qui représente le trafic réseau et les interactions entre différentes sources et destinations. Pour créer le graphique, vous pouvez utiliser l’opérateur make-graph spécifiant les colonnes source et de destination en tant que points de terminaison de périphérie, et éventuellement fournir des colonnes supplémentaires en tant que propriétés de bord ou de nœud.
La requête suivante crée un graphique à partir des journaux bruts :
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;
Cette requête analyse les journaux bruts et crée un graphique dirigé où les nœuds sont des adresses IP ou des ressources, et chaque arête est une requête de la source vers la destination, avec l’horodatage et le verbe HTTP en tant que propriétés de périphérie.
Une fois le graphique créé, vous pouvez utiliser l’opérateur de correspondance de graphique pour interroger les données de graphe à l’aide de modèles, de filtres et de projections. Par exemple, vous pouvez créer un modèle qui effectue une recommandation simple en fonction des ressources demandées par d’autres adresses IP demandées au cours des cinq dernières minutes, comme suit :
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
Sortie
Recommandation |
---|
/product/42 |
La requête retourne « /product/42 » comme recommandation basée sur un journal texte brut.