借助 Kusto 中的图形语义,可以将数据建模和查询为互连网络,从而直观地分析复杂的关系,例如组织层次结构、社交网络和攻击路径。 与依赖于联接的传统关系查询不同,图形使用实体之间的直接关系高效遍历连接。
本教程中,您将学习如何:
先决条件
- 用于登录到帮助群集的 Microsoft 帐户或 Microsoft Entra 用户标识
访问查询环境
打开 Azure 数据资源管理器 Web UI 以访问本教程的帮助群集。
导航到高级搜寻页,开始查询Microsoft Sentinel 数据。
导航到 Azure 门户中的“日志”或“日志分析”工作区,开始查询 Azure Monitor 数据。
使用组织数据创建暂时性图形
在本部分中,你将使用示例组织数据创建第一个图形。 使用运算符make-graph
在查询执行期间动态创建瞬态图,使它们非常适合临时分析和探索。
你将使用一个简单的公司结构,其中员工向经理报告。 此组织层次结构提供了一个直观的示例,用于理解图形关系:
使用员工和报告关系数据创建组织结构图:
// 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
输出
姓名 | 角色 | 年龄 |
---|---|---|
爱丽丝 | 首席执行官 | 45 |
鲍勃 | 工程经理 | 35 |
颂歌 | 市场营销经理 | 三十八 |
戴夫 | 开发 人员 | 28 |
前夕 | 开发 人员 | 26 |
弗兰克 | 营销专家 | 30 |
使用图形匹配模式查询关系
现在,你将了解如何使用 graph-match
作员在组织结构图中查找特定模式。 运算符 graph-match
在图形结构中搜索关系和连接。
首先,通过匹配即时报告关系模式查找直接向 Alice 报告的所有员工:
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
直接报告输出
员工 | 角色 | 年龄 |
---|---|---|
鲍勃 | 工程经理 | 35 |
颂歌 | 市场营销经理 | 三十八 |
接下来,查找 Alice 整个组织中的所有员工,包括间接下属,使用可变长度的边 *1..3
来遍历组织层级的多个级别。
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)
所有组织成员的输出
员工 | 角色 | 报告级别 |
---|---|---|
鲍勃 | 工程经理 | 1 |
颂歌 | 市场营销经理 | 1 |
戴夫 | 开发 人员 | 2 |
前夕 | 开发 人员 | 2 |
弗兰克 | 营销专家 | 2 |
创建持久图形模型
注释
此功能目前处于公开预览状态。 正式发布之前,功能和语法可能会更改。
持久图存储在数据库中,无需重新生成图形结构即可重复查询。 现在,你将创建与持久图形相同的组织结构,以提高性能和可重用性。
创建返回示例数据的函数,然后定义图形模型结构:
// 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"
]
}
使用节点和边缘架构定义图形模型:
.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"]
}
]
}
}
```
创建图形快照,将模型具体化为可查询结构:
.make graph_snapshot OrganizationGraph_v1 from OrganizationGraph
查询永久性图形
使用与暂时性图形相同的模式查询永久性图形。 查找向 Alice 报告的所有员工:
graph("OrganizationGraph")
| graph-match (alice)<-[reports]-(employee)
where alice.name == "Alice"
project employee = employee.name, role = employee.role, age = employee.age
查找 Alice 组织中包括间接报表在内的所有员工:
graph("OrganizationGraph")
| graph-match (alice)<-[reports*1..3]-(employee)
where alice.name == "Alice"
project employee = employee.name, role = employee.role, reportingLevels = array_length(reports)
如果需要,请查询特定的快照版本:
graph("OrganizationGraph", "OrganizationGraph_v1")
| graph-match (alice)<-[reports*1..3]-(employee)
where alice.name == "Alice"
project employee = employee.name, role = employee.role
比较暂时性图形和持久图
了解何时使用每个方法有助于为分析需求选择合适的方法:
方面 | 暂时性图形 | 持久图形 |
---|---|---|
创建 |
make-graph 查询时的运算符 |
.create-or-alter graph_model + .make graph_snapshot |
存储 | 在查询执行时运行于内存中 | 存储在数据库中 |
可 重用 | 必须为每个查询重新生成 | 重复查询而不重新生成 |
性能 | 适用于较小的数据集 | 针对大型复杂图形进行优化 |
用例 | 即席分析、探索 | 生产分析,重复查询 |
内存限制 | 受节点内存限制 | 可以处理更大的数据集 |
清理资源
如果不打算继续使用永久性图形模型,请使用以下命令将其删除:
删除图形模型:
.drop graph_model OrganizationGraph
删除帮助程序函数:
.drop function Employees .drop function Reports
当查询完成时,会自动清理暂时性图形,因此这些示例无需进行额外的清理。
后续步骤
了解 Kusto 中图形语义的基础知识后,请继续了解更复杂的方案和优化:
还可以浏览以下相关文章: