Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Aplica-se a: ✅Microsoft Fabric✅Azure Data Explorer✅Azure Monitor✅Microsoft Sentinel
O operador make-graph constrói uma estrutura gráfica a partir de entradas tabulares de arestas e nós.
Sintaxe
Bordas|make-graphSourceNodeId-->TargetNodeId [ withNodes1onNodeId1 [,Nodes2onNodeId2 ]]
Bordas|make-graphSourceNodeId-->TargetNodeId [ with_node_id=NodeIdPropertyName ]
Bordas|make-graphSourceNodeId-->TargetNodeId [ withNós1onNodeId1 [,Nós2onNodeId2 ]] partitioned-byPartitionColumn(GraphOperator)
Parâmetros
| Designação | Tipo | Necessário | Descrição |
|---|---|---|---|
| Bordas | string |
✔️ | A fonte tabular que contém as arestas do gráfico, cada linha representa uma aresta no gráfico. |
| SourceNodeId | string |
✔️ | A coluna em Bordas com as IDs do nó de origem das bordas. |
| TargetNodeId | string |
✔️ | A coluna em Bordas com as IDs do nó de destino das bordas. |
| Nós1, Nós2 | string |
As expressões tabulares que contêm as propriedades dos nós no gráfico. | |
| NodesId1, NodesId2 | string |
As colunas correspondentes com os IDs de nó em Nodes1Nodes2 respectivamente. | |
| NodeIdPropertyName | string |
O nome da propriedade para ID de nó nos nós do gráfico. | |
| PartitionColumn | string |
A coluna pela qual particionar o gráfico. Cria gráficos separados para cada valor exclusivo nesta coluna. | |
| Operador gráfico | string |
O operador gráfico a ser aplicado a cada gráfico particionado. |
Devoluções
O operador make-graph retorna uma expressão gráfica e deve ser seguido por um operador de gráfico . Cada linha na de origem expressão Bordas torna-se uma aresta no gráfico com propriedades que são os valores de coluna da linha. Cada linha no Nós expressão tabular torna-se um nó no gráfico com propriedades que são os valores de coluna da linha. Os nós que aparecem na tabela Edges, mas não têm uma linha correspondente na tabela Nodes, são criados como nós com a ID do nó correspondente e propriedades vazias.
Ao usar a partitioned-by cláusula, gráficos separados são criados para cada valor exclusivo na PartitionColumn especificada. O GraphOperator especificado é então aplicado a cada gráfico particionado independentemente, e os resultados são combinados em uma única saída. Isso é particularmente útil para cenários multilocatários em que você deseja analisar os dados de cada locatário separadamente, mantendo a mesma estrutura gráfica e lógica de análise.
Importante
Ao usar a partitioned-by cláusula, tanto a tabela Bordas quanto todas as tabelas de Nós devem conter a coluna de partição.
Observação
Cada nó tem um identificador exclusivo. Se o mesmo ID de nó aparecer nas tabelas
Os usuários podem manipular informações de nó das seguintes maneiras:
-
Nenhuma informação de nó necessária:
make-graphé concluída com origem e destino. -
Propriedades explícitas do nó: usar até duas expressões tabulares usando "
withNodes1onNodeId1 [,Nodes2onNodeId2 ]." -
Identificador de nó padrão: use "
with_node_id=DefaultNodeId."
Exemplo
Gráfico de arestas e nós
O exemplo a seguir cria um gráfico a partir de tabelas de bordas e nós. Os nós representam pessoas e sistemas, e as bordas representam diferentes relações entre nós. O operador make-graph constrói o gráfico. Em seguida, o operador graph-match é usado com um padrão gráfico para procurar caminhos de ataque que levam ao nó do sistema "Trent".
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
Output
| Atacante | Comprometido | Sistema |
|---|---|---|
| Mallory | Joaquim | Trento |
Identificador de nó padrão
O exemplo a seguir cria um gráfico usando apenas bordas, com a propriedade name como o identificador de nó padrão. Essa abordagem é útil ao criar um gráfico a partir de uma expressão tabular de bordas, garantindo que o identificador de nó esteja disponível para a seção de restrições do operador de graph-match subsequente.
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
Output
| Atacante | Comprometido | Sistema |
|---|---|---|
| Mallory | Joaquim | Trento |
Gráfico particionado
Este exemplo demonstra o uso da partitioned-by cláusula para analisar uma rede social multilocatário. A partitioned-by cláusula cria gráficos separados para cada valor exclusivo na coluna de partição (neste caso, tenantId), aplica o operador de gráfico a cada partição de forma independente e combina os 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 | Fim |
|---|---|---|
| Bob Smith (EmpresaA) | [ "EmpresaA", "EmpresaA" ] |
Diana Finch (EmpresaA) |
| Henry Davis (EmpresaB) | [ "EmpresaB", "EmpresaB" ] |
Grace Lee (EmpresaB) |