macro-expand operator

适用于:✅Azure 数据资源管理器

The macro-expand operator simplifies running a subquery on a set of entities, such as clusters, databases, or tables, and then combining the results into a single output.

当数据分散在多个群集、数据库或表之间时,运算符非常有用。 例如,当数据与其源位于同一全局区域中时,可以在不同位置的单个查询中使用 macro-expand 运算符,而不是为每个实体运行单独的查询并手动合并结果。

The set of entities you want to query is called an entity group. 可以存储实体组,以便在数据库中重复使用,也可以直接在查询文本中定义。 For more information about stored entity groups, see Entity groups.

macro-expand 运算符为组中的每个实体单独运行子查询,然后将所有结果合并到单个输出中。 子查询可以包含嵌套 macro-expand 运算符。 但是,内部 macro-expand 的标识符必须与外部 macro-expand 的标识符不同,才能清楚地区分每个 macro-expand 的范围和引用。

Syntax

macro-expand [kind=Kind] [isfuzzy=IsFuzzy] EntityGroupasEntityIdentifier(Subquery)

macro-expand [kind=Kind] [isfuzzy=IsFuzzy] entity_group[EntityReference [, ...] asEntityIdentifier(Subquery)``]

macro-expand EntityIdentifierinEntityGroupIdentifier(Subquery)

Note

macro-expand 运算符的作可以通过使用 best_effort 或通过 true来将 set statement 请求属性设置为 来修改。 当此属性设置为 true时,macro-expand 运算符将忽略模糊解析和连接失败,以执行正在联合的任何子表达式,并在查询状态结果中发出警告。

Variations

可通过多种方式指定 macro-expand 运算符使用的实体组:

  • Inline: All elements are explicitly defined in the text of the operator invocation itself. For an example, see Calculate errors.

  • Via let 语句: 使用语法 let 运算符外部的 macro-expand 语句在查询中指定实体组:

    let EntityGroupIdentifier=entity_group[EntityReference [, ...]]

    有关示例,请参阅 使用 let 语句计算 SKU 错误。

  • 使用存储实体组: 查询使用存储在数据库中的实体组,而不是在查询中定义。

    有关示例,请参阅 使用上下文标量函数扩展表。

Parameters

Name 类型 Required Description
Kind string innerouter(默认值)。 当 kind 设置为 inner时,结果仅包括所有访问的作用域实体共有的列。 如果设置为 outer,则结果包括任何输入中发生的所有列。 输入行未定义的单元格设置为 null
IsFuzzy 设置为 true时,它只考虑当前存在且可访问的实体源。 如果找到至少一个实体,查询将运行,并且任何缺失的实体在查询状态结果中生成警告。 如果未找到任何实体,查询将无法解析任何指定的实体并返回错误。 默认值为 false
EntityGroup ✔️ A set of one or more entities that EntityIdentifier expands into when a query is run. 实体组可以是存储的实体组或定义的组。 It denotes one or more entities of the same type that EntityIdentifier expands to.
EntityIdentifier string ✔️ 一个标识符,用作子查询中实体的占位符,并在运行查询时将其扩展为实际实体。 Entities that aren't explicitly scoped in EntityIdentifier are assumed to be part of the current in scope database. 查询中包含的任何特定标识符将替代默认假设。
EntityReference string 实体组中包含的实体。 One or more EntityReference is required if an EntityGroup isn't specified.
Subquery string ✔️ 不直接获取输入数据的单个表格表达式。 It might include references to entities through an EntityIdentifier, and use expressions such as let statements, stored functions, or other elements from the database in scope. Subquery can be preceded by one or more let statements. 它还可以引用子查询上下文函数

Note

查询只能引用在查询文本或当前数据库中定义的实体组。 不能直接或间接引用其他数据库或群集中的实体组。

子查询上下文标量

macro-expand 查询可以引用两个专用标量值,就好像它们是被引用的实体的一部分:

  • $current_database - 返回实体引用的数据库名称(a string)。
  • $current_cluster_endpoint - 返回实体引用群集的 URL(a string)。

Note

These values can only be used when they are scoped by the EntityReference. For example, if EntityReference is a database and the macro-expand is using DB to reference the database, use DB.$current_cluster_endpoint to retrieve the URL of the cluster which hosts the database.

Examples

以下示例演示如何使用 macro-expand运算符。

Calculate errors

The following example uses an inline variation entity group to calculate the number of errors produced by each Stock Keeping Unit (SKU). 它定义一个 entity_groupX),其中包括两个群集中名为 MyDatabase 的数据库。 然后,该查询执行子查询以筛选错误日志,并通过 Source对错误进行计数。 接下来,它会使用 inner 表对 Source 执行 DimCluster 联接,以获取每个源的 SKU。 最后,它通过 SKU对错误计数求和。

macro-expand entity_group [cluster('C1').database('MyDatabase'), cluster('C2').database('MyDatabase')] as X
(
    X.Logs
    | where Level == 'Error'
    | summarize Count=count() by Source
    | join kind=inner (X.DimCluster | project SKU, Source) on Source
)
| summarize Sum=sum(Count) by SKU
  • summarize 运算符适用于所有展开的子查询的组合结果,而 macro-expand 运算符仅应用于括号之间的子查询,因此明确了哪个范围已展开。

  • join 运算符针对 entity_group中的每个实体单独执行。 在此示例中,join 在同一实体中的两个表之间执行,由 X表示。 这意味着没有跨群集 join

若要在不使用 macro-expand的情况下编写相同的查询,其外观可能如下所示:

union
  (
    cluster('C1').database('MyDatabase').Logs
    | where Level == 'Error'
    | summarize Count=count() by Source
    | join kind=inner (cluster('C1').database('MyDatabase').DimCluster | project SKU, Source) on Source
  ),
  (
    cluster('C2').database('MyDatabase').Logs
    | where Level == 'Error'
    | summarize Count=count() by Source
    | join kind=inner (cluster('C2').database('MyDatabase').DimCluster | project SKU, Source) on Source
  )
| summarize Sum=sum(Count) by SKU

使用 let 语句计算 SKU 错误

以下示例使用 let 语句 在名为 Greater 的变量中定义实体组,其中包括 MyDatabaseC1 群集中的 C2 数据库。 This entity group is then used to perform the same query in the previous example to calculate the number of errors produced by each SKU. macro-expand 运算符用于引用 Greater 实体组(别名 X)。

let GreaterDatabase = entity_group [cluster('C1').database('MyDatabase'), cluster('C2').database('MyDatabase')];
macro-expand GreaterDatabase as X
(
    X.Logs
    | where Level == 'Error'
    | summarize Count=count() by Source
    | join kind=inner (X.DimCluster | project SKU, Source) on Source
)
| summarize Sum=sum(Count) by SKU

使用上下文标量函数扩展表

以下查询使用 存储实体组 变体。 它使用存储的实体组 Admins对每个实体的 MyEntityGroup 表运行子查询。 有关如何创建存储实体的详细信息,请参阅 .create entity_group 命令。 它使用 $current_database$current_cluster_endpoint 来扩展表,为每个行添加当前数据库和当前群集。 然后,它通过计算 current_clustercurrent_database的每个组合的行数来汇总结果。

macro-expand MyEntityGroup as X
(
    X.Admins
    | extend current_database = X.$current_database, current_cluster = X.$current_cluster_endpoint
)
| summarize count() by current_cluster, current_database

嵌套宏扩展查询

以下查询运行嵌套子查询,其中包含外部实体组 MyEntityGroup_Outer(别名 X)和内部实体组 MyEntityGroup_Inner(别名 Y)。 它将外部(Admins)和内部(X)实体组中的每个实体联接 Y 表。 查询筛选过去一小时内的日志。 然后,它扩展表以使用 $current_database$current_cluster_endpoint包含每行的当前数据库和群集。 查询对 join 列执行 Source,以合并内部和外部实体组。 前缀 lhs(左侧)和 rhs(右侧)分别表示 XY 实体组。 最后,它通过计算 lhs_clusterlhs_databaserhs_clusterrhs_database的每个组合的行数来汇总结果。

macro-expand MyEntityGroup_Outer as X
(
    macro-expand  MyEntityGroup_Inner as Y
    (
        X.Admins
        | where Timestamp > ago(1h)
        | extend lhs_database = X.$current_database, lhs_cluster = X.$current_cluster_endpoint
        | join (
            Y.Admins
            | where Timestamp > ago(1h)
            | extend rhs_database = Y.$current_database, rhs_cluster = Y.$current_cluster_endpoint
        ) on Source
    )
)
| summarize count() by lhs_cluster, lhs_database, rhs_cluster, rhs_database