Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Se aplica a: ✅Microsoft Fabric✅Azure Data Explorer✅Azure Monitor✅Microsoft 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:
-
No se requiere información de nodo:
make-graphse completa con el origen y el destino. -
Propiedades de nodo explícitas: use hasta dos expresiones tabulares mediante "
withNodeId1 [onNodeId2 ]." -
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.
// 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) |