¿Cuáles son los escenarios comunes para usar la semántica de grafos de Lenguaje de consulta Kusto (KQL)?
La semántica de grafos en Lenguaje de consulta Kusto (KQL) permite modelar y consultar datos como grafos. Hay muchos escenarios en los que los gráficos son útiles para representar datos complejos y dinámicos que implican relaciones de varios a varios, jerárquicos o en red, como redes sociales, sistemas de recomendación, recursos conectados o gráficos de conocimiento.
En este artículo, obtendrá información sobre los siguientes escenarios comunes para usar la semántica de grafos KQL:
Amigos de un amigo
Un caso de uso común para los gráficos es modelar y consultar redes sociales, donde los nodos son usuarios y bordes son amistades o interacciones. Por ejemplo, imagine que tenemos una tabla denominada Usuarios que tiene datos sobre los usuarios, como su nombre y organización, y una tabla denominada Conoce que tiene datos sobre las amistades entre los usuarios, como se muestra en el diagrama siguiente:
Sin usar la semántica de grafos en KQL, podría crear un grafo para buscar amigos de un amigo mediante varias combinaciones, como se indica a continuación:
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
Puede usar la semántica de grafos en KQL para realizar la misma consulta de forma más intuitiva y eficaz. La consulta siguiente usa el operador make-graph para crear un grafo dirigido de FirstUser a SecondUser y enriquece las propiedades de los nodos con las columnas proporcionadas por la tabla Users. Una vez que se crea una instancia del grafo, el operador graph-match proporciona el patrón friend-of-a-friend, incluidos los filtros y una proyección que da como resultado una salida 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
Ideas de datos de registro
En algunos casos de uso, quiere obtener información de una tabla plana sencilla que contenga información de series temporales, como los datos de registro. Los datos de cada fila son una cadena que contiene datos sin procesar. Para crear un grafo a partir de estos datos, primero debe identificar las entidades y relaciones que son relevantes para el análisis de grafos. Por ejemplo, supongamos que tiene una tabla denominada rawLogs desde un servidor web que contiene información sobre las solicitudes, como la marca de tiempo, la dirección IP de origen, el recurso de destino y mucho más.
En la tabla siguiente se muestra un ejemplo de los datos sin procesar:
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\" \"-\""
];
Una posible manera de modelar un grafo de esta tabla es tratar las direcciones IP de origen como nodos y las solicitudes web a los recursos como bordes. Puede usar el operador de análisis para extraer las columnas que necesita para el grafo y, a continuación, puede crear un grafo que represente el tráfico de red y las interacciones entre diferentes orígenes y destinos. Para crear el grafo, puede usar el operador make-graph que especifica las columnas de origen y destino como puntos de conexión perimetrales y, opcionalmente, proporcionar columnas adicionales como propiedades perimetrales o de nodo.
La consulta siguiente crea un gráfico a partir de los registros sin procesar:
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 analiza los registros sin procesar y crea un gráfico dirigido donde los nodos son direcciones IP o recursos y cada borde es una solicitud del origen al destino, con la marca de tiempo y el verbo HTTP como propiedades perimetrales.
Una vez creado el grafo, puede usar el operador graph-match para consultar los datos del grafo mediante patrones, filtros y proyecciones. Por ejemplo, puede crear un patrón que haga una recomendación sencilla basada en los recursos que otras direcciones IP solicitaron en los últimos cinco minutos, como se indica a continuación:
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
Salida
Recomendación |
---|
/product/42 |
La consulta devuelve "/product/42" como recomendación basada en un registro basado en texto sin formato.