Condividi tramite


Esercitazione: Creare i primi grafici nel linguaggio di query Kusto

Cambiare i servizi usando l'elenco a discesa Versione. Altre informazioni sulla navigazione.
Si applica a: ✅ Microsoft Fabric ✅ Esplora dati di Azure ✅ Azure Monitor ✅ Microsoft Sentinel

La semantica del grafo in Kusto consente di modellare ed eseguire query sui dati come reti interconnesse, rendendola intuitiva per analizzare relazioni complesse come gerarchie organizzative, social network e percorsi di attacco. A differenza delle query relazionali tradizionali che si basano su join, i grafici usano relazioni dirette tra entità per attraversare le connessioni in modo efficiente.

In questa esercitazione si apprenderà come:

Se non si ha un cluster di Esplora dati di Azure, crea un cluster gratuito prima di iniziare il tutorial.

Prerequisiti

  • Un account Microsoft o un'identità utente di Microsoft Entra per accedere al cluster della Guida

Accedere all'ambiente di query

Aprire l'interfaccia web di Azure Data Explorer per accedere al cluster di supporto per questa esercitazione.

Passare all'area di lavoro di Microsoft Fabric e aprire un database KQL per eseguire le query.

Passare alla pagina ricerca avanzata per iniziare a eseguire query sui dati di Microsoft Sentinel.

Passare ai Registri o a un'area di lavoro Log Analytics nel portale di Azure per iniziare a eseguire query sui dati di Azure Monitor.

Creare un grafico temporaneo con i dati dell'organizzazione

In questa sezione si creerà il primo grafo usando i dati dell'organizzazione di esempio. I grafici temporanei vengono creati dinamicamente durante l'esecuzione di query usando l'operatore make-graph, rendendoli perfetti per l'analisi e l'esplorazione ad hoc.

Si lavorerà con una semplice struttura aziendale in cui i dipendenti segnalano ai manager. Questa gerarchia organizzativa offre un esempio intuitivo per la comprensione delle relazioni tra i grafici:

Diagramma che mostra la gerarchia dell'organizzazione.

Creare la struttura del grafo dell'organizzazione usando i dati sui dipendenti e sulle relazioni gerarchiche.

// Create sample employee data
let employees = datatable(name:string, role:string, age:long) 
[ 
  "Alice", "CEO", 45,  
  "Bob", "Engineering Manager", 35,  
  "Carol", "Marketing Manager", 38,  
  "Dave", "Developer", 28,  
  "Eve", "Developer", 26,
  "Frank", "Marketing Specialist", 30
]; 
// Create reporting relationships
let reports = datatable(employee:string, manager:string) 
[ 
  "Bob", "Alice",  
  "Carol", "Alice",  
  "Dave", "Bob",
  "Eve", "Bob",
  "Frank", "Carol"
]; 
// Build the graph and explore it
reports 
| make-graph employee --> manager with employees on name 
| graph-to-table nodes 

Risultato

nome ruolo età
Alice Amministratore delegato 45
Bob Responsabile Ingegneria 35
Carola Responsabile Marketing 38
Dave Sviluppatore 28
Vigilia Sviluppatore 26
Franco Specialista marketing 30

Interrogare relazioni con modelli di corrispondenza di grafi

A questo punto si apprenderà come usare l'operatore graph-match per trovare modelli specifici nel grafico dell'organizzazione. L'operatore graph-match cerca relazioni e connessioni all'interno della struttura del grafo.

Prima di tutto, individuare tutti i dipendenti che riportano direttamente ad Alice, identificando il modello di relazione di rendicontazione immediata.

let employees = datatable(name:string, role:string, age:long) 
[ 
  "Alice", "CEO", 45,  
  "Bob", "Engineering Manager", 35,  
  "Carol", "Marketing Manager", 38,  
  "Dave", "Developer", 28,  
  "Eve", "Developer", 26,
  "Frank", "Marketing Specialist", 30
]; 
let reports = datatable(employee:string, manager:string) 
[ 
  "Bob", "Alice",  
  "Carol", "Alice",  
  "Dave", "Bob",
  "Eve", "Bob",
  "Frank", "Carol"
]; 
reports 
| make-graph employee --> manager with employees on name 
| graph-match (alice)<-[reports]-(employee)
  where alice.name == "Alice"  
  project employee = employee.name, role = employee.role, age = employee.age

Output dei rapporti diretti

impiegato ruolo età
Bob Responsabile Ingegneria 35
Carola Responsabile Marketing 38

Trovare quindi tutti i dipendenti nell'intera organizzazione di Alice, inclusi i report indiretti, usando bordi di lunghezza variabile con *1..3 per attraversare più livelli della gerarchia:

let employees = datatable(name:string, role:string, age:long) 
[ 
  "Alice", "CEO", 45,  
  "Bob", "Engineering Manager", 35,  
  "Carol", "Marketing Manager", 38,  
  "Dave", "Developer", 28,  
  "Eve", "Developer", 26,
  "Frank", "Marketing Specialist", 30
]; 
let reports = datatable(employee:string, manager:string) 
[ 
  "Bob", "Alice",  
  "Carol", "Alice",  
  "Dave", "Bob",
  "Eve", "Bob",
  "Frank", "Carol"
]; 
reports 
| make-graph employee --> manager with employees on name 
| graph-match (alice)<-[reports*1..3]-(employee)
  where alice.name == "Alice"
  project employee = employee.name, role = employee.role, reportingLevels = array_length(reports)

Output di tutti i membri dell'intera organizzazione

impiegato ruolo Livelli di segnalazione
Bob Responsabile Ingegneria 1
Carola Responsabile Marketing 1
Dave Sviluppatore 2
Vigilia Sviluppatore 2
Franco Specialista marketing 2

Creare un modello a grafo permanente

Annotazioni

Questa funzionalità è attualmente disponibile in anteprima pubblica. La funzionalità e la sintassi sono soggette a modifiche prima della disponibilità generale.

I grafici permanenti vengono archiviati nel database e possono essere sottoposti ripetutamente a query senza ricompilare la struttura del grafo. A questo punto si creerà la stessa struttura organizzativa di un grafico permanente per migliorare le prestazioni e la riutilizzabilità.

Creare funzioni che restituiscono i dati di esempio, quindi definire una struttura del modello a grafo:

// Create a function that returns employee data
.create function Employees() {
    datatable(name: string, role: string, age: long)
    [
        "Alice", "CEO", 45,
        "Bob", "Engineering Manager", 35,
        "Carol", "Marketing Manager", 38,
        "Dave", "Developer", 28,
        "Eve", "Developer", 26,
        "Frank", "Marketing Specialist", 30
    ]
}

// Create a function that returns reporting relationships
.create function Reports() {
    datatable(employee: string, manager: string)
    [
        "Bob", "Alice",
        "Carol", "Alice",
        "Dave", "Bob",
        "Eve", "Bob",
        "Frank", "Carol"
    ]
}

Definire il modello a grafo con schemi di nodi e archi:

.create-or-alter graph_model OrganizationGraph ```
{
    "Schema": {
        "Nodes": {
            "Employee": {
                "name": "string",
                "role": "string",
                "age": "long"
            }
        },
        "Edges": {
            "ReportsTo": {
            }
        }
    },
    "Definition": {
        "Steps": [
            {
                "Kind": "AddNodes",
                "Query": "Employees()",
                "NodeIdColumn": "name",
                "Labels": ["Employee"]
            },
            {
                "Kind": "AddEdges",
                "Query": "Reports()",
                "SourceColumn": "employee",
                "TargetColumn": "manager",
                "Labels": ["ReportsTo"]
            }
        ]
    }
}
```

Creare uno snapshot del grafo per materializzare il modello in una struttura interrogabile.

.make graph_snapshot OrganizationGraph_v1 from OrganizationGraph

Eseguire query sul grafico permanente

Eseguire una query sul grafico permanente usando gli stessi modelli dei grafici temporanei. Trovare tutti i dipendenti che segnalano ad Alice:

graph("OrganizationGraph")
| graph-match (alice)<-[reports]-(employee)
  where alice.name == "Alice"
  project employee = employee.name, role = employee.role, age = employee.age

Trovare tutti i dipendenti nell'organizzazione di Alice, inclusi i report indiretti:

graph("OrganizationGraph")
| graph-match (alice)<-[reports*1..3]-(employee)
  where alice.name == "Alice"
  project employee = employee.name, role = employee.role, reportingLevels = array_length(reports)

Effettuare una query su una versione specifica dello snapshot, se necessario.

graph("OrganizationGraph", "OrganizationGraph_v1")
| graph-match (alice)<-[reports*1..3]-(employee)
  where alice.name == "Alice"
  project employee = employee.name, role = employee.role

Confrontare grafici temporanei e persistenti

Comprendere quando usare ogni approccio consente di scegliere il metodo giusto per le esigenze di analisi:

Aspetto Grafici temporanei Grafici permanenti
Creazione make-graph operatore durante la query .create-or-alter graph_model + .make graph_snapshot
Spazio di archiviazione In memoria durante l'esecuzione di query Archiviato nel database
riutilizzabilità Deve essere ricompilata per ogni query Eseguire ripetutamente una query senza ricompilare
Prestazioni Valido per set di dati più piccoli Ottimizzato per grafici complessi di grandi dimensioni
Casi d'uso Analisi ad hoc, esplorazione Analisi di produzione, interrogazioni ripetute
Limiti di memoria Limitato dalla memoria del nodo Può gestire set di dati di dimensioni maggiori

Pulire le risorse

Se non si intende continuare a usare i modelli a grafo persistente, eliminarli con i comandi seguenti:

  1. Eliminare il modello a grafo:

    .drop graph_model OrganizationGraph
    
  2. Eliminare le funzioni di supporto:

    .drop function Employees
    .drop function Reports
    

I grafici temporanei vengono puliti automaticamente al termine della query, quindi non è necessaria alcuna pulizia aggiuntiva per tali esempi.

Passaggi successivi

Ora che si conoscono le nozioni di base della semantica del grafo in Kusto, passare a scenari e ottimizzazioni più complessi:

È anche possibile esplorare questi articoli correlati: