Partager via


Opérateur make-graph

S’applique à : ✅Microsoft Fabric

L’opérateur make-graph génère une structure de graphe à partir d’entrées tabulaires de bords et de nœuds.

Syntaxe

Edges|make-graph[ --> [withon ]]

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

Bords|make-graphSourceNodeId-->TargetNodeId [ withNode1onNodeId1 [,Node2onNodeId2 ]] partitioned-byPartitionColumn(GraphOperator)

Paramètres

Nom Type Requise Description
Bords string ✔️ Source tabulaire contenant les bords du graphe, chaque ligne représente un bord dans le graphique.
SourceNodeId string ✔️ Colonne dans Edges avec les ID de nœud source des bords.
TargetNodeId string ✔️ Colonne dans Edges avec les ID de nœud cible des bords.
Nœuds1, Nœuds2 string Expressions tabulaires contenant les propriétés des nœuds dans le graphique.
NodeId1, NodeId2 string Colonnes correspondantes avec les ID de nœud dans Node1, Nœuds2 respectivement.
NodeIdPropertyName string Nom de la propriété pour l’ID de nœud sur les nœuds du graphique.
PartitionColumn string Colonne par laquelle partitionner le graphique. Crée des graphiques distincts pour chaque valeur unique dans cette colonne.
GraphOperator string Opérateur de graphe à appliquer à chaque graphique partitionné.

Retours

L’opérateur make-graph retourne une expression de graphe et doit être suivi d’un opérateur de graphe. Chaque ligne de l’expression Edges source devient un bord dans le graphique avec des propriétés qui sont les valeurs de colonne de la ligne. Chaque ligne de l’expression tabulaire Nœuds devient un nœud dans le graphique avec des propriétés qui sont les valeurs de colonne de la ligne. Les nœuds qui apparaissent dans la table Edges , mais qui n’ont pas de ligne correspondante dans la table Nœuds , sont créés en tant que nœuds avec l’ID de nœud correspondant et les propriétés vides.

Lorsque vous utilisez la partitioned-by clause, des graphiques distincts sont créés pour chaque valeur unique dans le PartitionColumn spécifié. GraphOperator spécifié est ensuite appliqué à chaque graphique partitionné indépendamment, et les résultats sont combinés en une seule sortie. Cela est particulièrement utile pour les scénarios multilocataires dans lesquels vous souhaitez analyser les données de chaque locataire séparément tout en conservant la même structure de graphe et la même logique d’analyse.

Important

Lorsque vous utilisez la partitioned-by clause, la table Edges et toutes les tables Nœuds doivent contenir la colonne de partition.

Remarque

Chaque nœud a un identificateur unique. Si le même ID de nœud apparaît dans les tables Node1 et Node2 , un nœud unique est créé en fusionnant leurs propriétés. S’il existe des valeurs de propriété conflictuelles pour le même nœud, l’une des valeurs est arbitrairement choisie.

Les utilisateurs peuvent gérer les informations de nœud de la manière suivante :

  1. Aucune information de nœud requise :make-graph se termine avec la source et la cible.
  2. Propriétés de nœud explicites : utilisez jusqu’à deux expressions tabulaires à l’aide de « withNodeId1 [ onNodeId2 ]. »
  3. Identificateur de nœud par défaut : utilisez «with_node_id=DefaultNodeId ».

Exemple

Graphique des arêtes et des nœuds

L’exemple suivant génère un graphique à partir de tableaux de bords et de nœuds. Les nœuds représentent des personnes et des systèmes, et les arêtes représentent différentes relations entre les nœuds. L’opérateur make-graph génère le graphique. Ensuite, l’opérateur graph-match est utilisé avec un modèle de graphique pour rechercher des chemins d’attaque menant au "Trent" nœud système.

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

Sortie

Attaquant Compromis System
Mallory Bob Trent

Identificateur de nœud par défaut

L’exemple suivant génère un graphique à l’aide de bords uniquement, avec la name propriété comme identificateur de nœud par défaut. Cette approche est utile lors de la création d’un graphique à partir d’une expression tabulaire de bords, ce qui garantit que l’identificateur de nœud est disponible pour la section contraintes de l’opérateur suivant 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

Sortie

Attaquant Compromis System
Mallory Bob Trent

Graphique partitionné

Cet exemple montre comment utiliser la partitioned-by clause pour analyser un réseau social mutualisé. La partitioned-by clause crée des graphiques distincts pour chaque valeur unique dans la colonne de partition (dans ce cas, tenantId), applique l’opérateur de graphe à chaque partition indépendamment et combine les résultats.

Diagramme montrant trois sociétés différentes qui représentent trois partitions différentes.

// 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, ")")
)
Démarrer Locataires Fin
Bob Smith (CompanyA) [
« CompanyA »,
« CompanyA »
]
Diana Finch (CompanyA)
Henry Davis (CompanyB) [
« CompanyB »,
« CompanyB »
]
Grace Lee (CompanyB)