Compartir a través de


Operador make-graph

Se aplica a: ✅Microsoft FabricAzure Data Explorer✅Azure MonitorMicrosoft Sentinel

El make-graph operador crea una estructura de grafo a partir de entradas tabulares de bordes y nodos.

Sintaxis

Edges|make-graph SourceNodeId TargetNodeId--> [ withNodes1on NodeId1 [,Nodes2 NodeId2on]]

Bordes|make-graphSourceNodeId-->TargetNodeId [ with_node_id=NodeIdPropertyName ]

Bordes|make-graphSourceNodeId-->TargetNodeId [ withNodes1onNodeId1 [,Nodes2on ]] partitioned-byPartitionColumn(GraphOperator)

Parámetros

Nombre Type Obligatorio Descripción
Bordes string ✔️ Origen tabular que contiene los bordes del grafo, cada fila representa un borde del grafo.
SourceNodeId string ✔️ Columna en Bordes con los identificadores de nodo de origen de los bordes.
TargetNodeId string ✔️ Columna en Bordes con los identificadores de nodo de destino de los bordes.
Nodes1, Nodes2 string Expresiones tabulares que contienen las propiedades de los nodos del gráfico.
NodesId1, NodesId2 string Las columnas correspondientes con los identificadores de nodo de Nodes1, Nodes2 respectivamente.
nodeIdPropertyName string Nombre de la propiedad para el identificador de nodo en los nodos del grafo.
PartitionColumn string Columna por la que se va a particionar el grafo. Crea gráficos independientes para cada valor único de esta columna.
GraphOperator string Operador de grafo que se va a aplicar a cada grafo con particiones.

Devoluciones

El make-graph operador devuelve una expresión de grafo y debe ir seguida de un operador de grafo. Cada fila de la expresión Edges de origen se convierte en un borde del gráfico con propiedades que son los valores de columna de la fila. Cada fila de la expresión tabular Nodos se convierte en un nodo del grafo con propiedades que son los valores de columna de la fila. Los nodos que aparecen en la tabla Edges , pero que no tienen una fila correspondiente en la tabla Nodos se crean como nodos con el identificador de nodo correspondiente y las propiedades vacías.

Al usar la partitioned-by cláusula , se crean gráficos independientes para cada valor único en partitionColumn especificado. A continuación, graphOperator especificado se aplica a cada grafo con particiones de forma independiente y los resultados se combinan en una única salida. Esto es especialmente útil para escenarios multiinquilino en los que desea analizar los datos de cada inquilino por separado, al tiempo que mantiene la misma lógica de análisis y estructura de grafos.

Importante

Al usar la partitioned-by cláusula , tanto la tabla Edges como todas las tablas Nodes deben contener la columna de partición.

Nota:

Cada nodo tiene un identificador único. Si aparece el mismo identificador de nodo en las tablas Nodes1 y Nodes2 , se crea un único nodo mediante la combinación de sus propiedades. Si hay valores de propiedad en conflicto para el mismo nodo, se elige arbitrariamente uno de los valores.

Los usuarios pueden controlar la información del nodo de las maneras siguientes:

  1. No se requiere información de nodo:make-graph se completa con el origen y el destino.
  2. Propiedades de nodo explícitas: use hasta dos expresiones tabulares mediante " withNodeId1 [ onNodeId2 ]."
  3. Identificador de nodo predeterminado: use "with_node_id=DefaultNodeId".

Ejemplo

Gráfico de bordes y nodos

En el ejemplo siguiente se compila un grafo a partir de bordes y tablas de nodos. Los nodos representan personas y sistemas, y los bordes representan relaciones diferentes entre los nodos. El make-graph operador compila el grafo. A continuación, el graph-match operador se usa con un patrón de grafo para buscar rutas de acceso de ataque que conducen al nodo del "Trent" sistema.

let nodes = datatable(name:string, type:string, age:int) 
[ 
  "Alice", "Person", 23,  
  "Bob", "Person", 31,  
  "Eve", "Person", 17,  
  "Mallory", "Person", 29,  
  "Trent", "System", 99 
]; 
let edges = datatable(Source:string, Destination:string, edge_type:string) 
[ 
  "Alice", "Bob", "communicatesWith",  
  "Alice", "Trent", "trusts",  
  "Bob", "Trent", "hasPermission",  
  "Eve", "Alice", "attacks",  
  "Mallory", "Alice", "attacks",  
  "Mallory", "Bob", "attacks"  
]; 
edges 
| make-graph Source --> Destination with nodes on name 
| graph-match (mallory)-[attacks]->(compromised)-[hasPermission]->(trent) 
  where mallory.name == "Mallory" and trent.name == "Trent" and attacks.edge_type == "attacks" and hasPermission.edge_type == "hasPermission" 
  project Attacker = mallory.name, Compromised = compromised.name, System = trent.name

Salida

Atacante Comprometido Sistema
Mallory Bob Trent

Identificador de nodo predeterminado

En el ejemplo siguiente se compila un grafo con solo bordes, con la name propiedad como identificador de nodo predeterminado. Este enfoque es útil al crear un grafo a partir de una expresión tabular de bordes, lo que garantiza que el identificador de nodo está disponible para la sección de restricciones del operador posterior graph-match .

let edges = datatable(source:string, destination:string, edge_type:string) 
[ 
  "Alice", "Bob", "communicatesWith",  
  "Alice", "Trent", "trusts",  
  "Bob", "Trent", "hasPermission",  
  "Eve", "Alice", "attacks",  
  "Mallory", "Alice", "attacks",  
  "Mallory", "Bob", "attacks"  
]; 
edges 
| make-graph source --> destination with_node_id=name
| graph-match (mallory)-[attacks]->(compromised)-[hasPermission]->(trent) 
  where mallory.name == "Mallory" and trent.name == "Trent" and attacks.edge_type == "attacks" and hasPermission.edge_type == "hasPermission" 
  project Attacker = mallory.name, Compromised = compromised.name, System = trent.name

Salida

Atacante Comprometido Sistema
Mallory Bob Trent

Gráfico particionado

En este ejemplo se muestra el uso de la partitioned-by cláusula para analizar una red social multiinquilino. La partitioned-by cláusula crea gráficos independientes para cada valor único en la columna de partición (en este caso, tenantId), aplica el operador de grafo a cada partición de forma independiente y combina los resultados.

Diagrama que muestra tres empresas diferentes que representan tres particiones diferentes.

// Nodes table representing users across multiple tenants (organizations)
let nodes = datatable(userId:string, tenantId:string, name:string, department:string, role:string, location:dynamic) 
[
    // Tenant: CompanyA - San Francisco Bay Area
    "u001", "CompanyA", "Alice Johnson", "Engineering", "Senior Developer", dynamic({"type": "Point", "coordinates": [-122.4194, 37.7749]}),
    "u002", "CompanyA", "Bob Smith", "Engineering", "Team Lead", dynamic({"type": "Point", "coordinates": [-122.4094, 37.7849]}),
    "u003", "CompanyA", "Charlie Black", "Marketing", "Manager", dynamic({"type": "Point", "coordinates": [-122.4294, 37.7649]}),
    "u004", "CompanyA", "Diana Finch", "HR", "Director", dynamic({"type": "Point", "coordinates": [-122.3994, 37.7949]}),
    "u005", "CompanyA", "Eve Wilson", "Engineering", "Junior Developer", dynamic({"type": "Point", "coordinates": [-122.4394, 37.7549]}),
    // Tenant: CompanyB - New York Area  
    "u006", "CompanyB", "Frank Miller", "Sales", "Account Manager", dynamic({"type": "Point", "coordinates": [-74.0060, 40.7128]}),
    "u007", "CompanyB", "Grace Lee", "Engineering", "Senior Developer", dynamic({"type": "Point", "coordinates": [-74.0160, 40.7228]}),
    "u008", "CompanyB", "Henry Davis", "Marketing", "Specialist", dynamic({"type": "Point", "coordinates": [-73.9960, 40.7028]}),
    "u009", "CompanyB", "Ivy Chen", "Engineering", "Team Lead", dynamic({"type": "Point", "coordinates": [-74.0260, 40.7328]}),
    "u010", "CompanyB", "Jack Thompson", "Operations", "Manager", dynamic({"type": "Point", "coordinates": [-73.9860, 40.6928]}),
    // Tenant: CompanyC - Austin Area
    "u011", "CompanyC", "Kate Anderson", "Finance", "Analyst", dynamic({"type": "Point", "coordinates": [-97.7431, 30.2672]}),
    "u012", "CompanyC", "Liam Murphy", "Engineering", "Architect", dynamic({"type": "Point", "coordinates": [-97.7331, 30.2772]}),
    "u013", "CompanyC", "Maya Patel", "Product", "Manager", dynamic({"type": "Point", "coordinates": [-97.7531, 30.2572]}),
    "u014", "CompanyC", "Noah Garcia", "Engineering", "Developer", dynamic({"type": "Point", "coordinates": [-97.7631, 30.2472]}),
    "u015", "CompanyC", "Olivia Rodriguez", "Marketing", "Director", dynamic({"type": "Point", "coordinates": [-97.7231, 30.2872]})
];
// Edges table representing relationships/interactions between users
let edges = datatable(sourceUserId:string, targetUserId:string, tenantId:string, relationshipType:string, strength:int)
[
    // CompanyA relationships
    "u001", "u002", "CompanyA", "reportsTo", 9,
    "u005", "u002", "CompanyA", "reportsTo", 8,
    "u002", "u003", "CompanyA", "collaborates", 6,
    "u001", "u005", "CompanyA", "mentors", 7,
    "u003", "u004", "CompanyA", "collaborates", 5,
    "u001", "u003", "CompanyA", "communicates", 4,
    // CompanyB relationships
    "u007", "u009", "CompanyB", "reportsTo", 9,
    "u006", "u010", "CompanyB", "reportsTo", 8,
    "u008", "u006", "CompanyB", "collaborates", 6,
    "u009", "u010", "CompanyB", "communicates", 5,
    "u007", "u008", "CompanyB", "mentors", 7,
    "u006", "u007", "CompanyB", "collaborates", 6,
    // CompanyC relationships  
    "u014", "u012", "CompanyC", "reportsTo", 9,
    "u012", "u013", "CompanyC", "collaborates", 7,
    "u011", "u013", "CompanyC", "collaborates", 6,
    "u013", "u015", "CompanyC", "reportsTo", 8,
    "u012", "u015", "CompanyC", "communicates", 5,
    "u011", "u014", "CompanyC", "mentors", 6
];
edges
| make-graph sourceUserId --> targetUserId with nodes on userId partitioned-by tenantId (
    graph-match cycles=none (n1)-[e*2..4]->(n2)
        where n1.userId != n2.userId and all(e, relationshipType == "collaborates") and
            geo_distance_2points(todouble(n1.location.coordinates[0]), todouble(n1.location.coordinates[1]),
                             todouble(n2.location.coordinates[0]), todouble(n2.location.coordinates[1])) < 10000
        project Start = strcat(n1.name, " (", n1.tenantId, ")"), Tenants = map(e, tenantId), End = strcat(n2.name, " (", n2.tenantId, ")")
)
Start Inquilinos Fin
Bob Smith (CompanyA) [
"CompanyA",
"CompanyA"
]
Diana Finch (CompanyA)
Henry Davis (CompanyB) [
"CompanyB",
"CompanyB"
]
Grace Lee (CompanyB)