使用 Kusto.Language 定义语义分析的架构

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

Kusto.Language 包括语义分析功能,用于识别列、变量、函数和表等实体并将其与查询语法的不同部分相关联。 语义分析还会检查语义错误,以帮助确保查询的正确性。

为了执行语义分析,需要为查询中引用的实体定义架构。 本文介绍如何直接定义架构或使用来自服务器的架构。

符号

在 Kusto.Language 中,定义符号的过程是声明架构的一个基本方面。 它涉及创建表示数据库中的表和函数的对象,这些对象然后用于构造数据库对象。 (可选)数据库对象可用于创建群集对象。 此方法遵循自下而上的方法论,其中首先定义较低级别的实体,然后使用这些较低级别的组件构造更高级别的实体。

下表对符号进行了概述。

实体 符号语法
new TableSymbol(TableName, TableSchema)
函数 new FunctionSymbol(FunctionName, FunctionParameters, FunctionDefinition)
数据库 new DatabaseSymbol(DatabaseName, DatabaseEntity [, ...])
群集 new ClusterSymbol(ClusterName, Database [, ...])

声明架构

本部分介绍如何声明和使用表、函数和数据库符号来定义分析程序用于语义分析的架构。

以下步骤概述了如何创建和使用符号。 然后,代码示例演示了这些步骤的实际操作。

  1. 为数据库中的每个表创建 TableSymbol 实例。
  2. 为数据库中的每个函数创建 FunctionSymbol 实例。
  3. 声明 DatabaseSymbol,其中包含以前创建的 TableSymbolFunctionSymbol 实例。
  4. DatabaseSymbol 添加到 GlobalState,后者为分析程序提供群集和数据库上下文。
  5. 利用 ParseAndAnalyze 方法中返回的全局状态使用语义分析来分析查询
// 1. Define the schema for the Shapes table, including its columns: id, width, and height.
var shapes = new TableSymbol("Shapes", "(id: string, width: real, height: real)");

// 2. Define the functions TallShapes and ShortShapes with their respective parameters and logic.
var tallshapes = new FunctionSymbol("TallShapes", "{ Shapes | width < height; }");
var shortshapes = new FunctionSymbol("ShortShapes", "(maxHeight: real)", "{ Shapes | height < maxHeight; }");

// 3. Create a database symbol named "mydb" and include the previously defined symbols.
var mydb = new DatabaseSymbol("mydb", shapes, tallshapes, shortshapes);

// 4. Add the database symbol to the global state and set it as the default database.
//    A cluster symbol is also created to contain the database, and that cluster is set as the default.
var globalsWithMyDb = GlobalState.Default.WithDatabase(mydb);

// 5. Use the schemas to parse and perform semantic analysis on the query.
var query = "Shapes | where width > 10.0";
var code = KustoCode.ParseAndAnalyze(query, globalsWithMyDb);

使用来自服务器的架构

如果已具有数据库,则手动声明所有实体架构可能是一项繁琐且不必要的任务。 相反,可以查询数据库并检索所需的架构信息。 Kusto.Toolkit 库提供 API,用于直接从群集加载符号。

以下示例使用 SymbolLoader 系列类直接从群集访问数据库架构。

// Find available databases.
var connection = new KustoConnectionStringBuilder(...);
var loader = new ServerSymbolLoader(connection);
var names = await loader.LoadDatabaseNamesAsync();

// Load database schema into a symbol.
var loader = new ServerSymbolLoader(connection);
var db = await loader.LoadDatabaseAsync(dbName);

// Load database schema into the global state as the default database.
var globals = GlobalState.Default;
var loader = new ServerSymbolLoader(connection);
var globalsWithDB = await loader.AddOrUpdateDefaultDatabaseAsync(globals, dbName);
var parsed = KustoCode.ParseAndAnalyze(query, globalsWithDB);

有关更多示例,请参阅 SymbolLoaderSymbolResolver

使用多个数据库或群集

  1. 若要在 GlobalState 中包含多个数据库,请创建 ClusterSymbol

    以下示例创建一个群集,其中包含上一部分中的 DatabaseSymbol

    var mycluster = new ClusterSymbol("mycluster.kusto.chinacloudapi.cn", mydb);
    
  2. ClusterSymbol 作为具有默认数据库的默认群集添加到 GlobalState 中,或将其添加为额外的群集。 使用 cluster()database() 函数访问任何非默认群集或数据库。

    // Option 1: Add the cluster as the default with a specified default database.
    var globalsWithMyDefaultCluster = GlobalState.Globals.WithCluster(mycluster).WithDatabase(mydb);
    // Option 2: Add the cluster to the list of known clusters.
    var globalsWithMyClusterAdded = GlobalState.Globals.AddOrReplaceCluster(mycluster);
    
  3. 利用 ParseAndAnalyze 方法中返回的相关状态使用语义分析来分析查询

添加内置函数和聚合

即使服务器中不存在函数,也可以在调用 ParseAndAnalyze 方法时将它们添加到全局状态实例中。

以下示例添加一个在查询分析中使用的 minmax 伪函数。

var fnMinMax = new FunctionSymbol("minmax", ScalarTypes.Real, new Parameter("x", ScalarTypes.Real));
var globals = GlobalState.Default.WithAggregates(globals.Aggregates.Concat(new [] {fnMinMax}).ToArray());
var code = KustoCode.ParseAndAnalyze("T | summarize minmax(c)", globals);

注意

如果从全局状态中删除函数或聚合,则分析程序在使用函数或聚合时将生成错误。