dynamic 数据类型
dynamic
标量数据类型可以是以下任何值:
dynamic
值的数组,其中包含零个或零个以上的值,并从零开始编制索引。- 一个属性包,可将唯一的
string
值映射到dynamic
值。 此属性包有零个或零个以上的此类映射(称为“槽”),通过唯一的string
值进行索引编制。 这些槽是无序的。 - 下述任何基元标量数据类型的值:
bool
、datetime
、guid
、int
、long
、real
、string
和timespan
。 - NULL。 有关详细信息,请参阅 Null 值。
注意
dynamic
类型的值的限制为 1MB (2^20),未压缩。 如果记录中的单元格值超过 1MB,则该值将被删除并且引入会成功。 可以通过更改列的编码策略来增加列的MaxValueSize
。- 虽然
dynamic
类型看起来类似于 JSON,但是它可以保存 JSON 模型无法表示的不存在于 JSON 中的值(例如,long
、real
、datetime
、timespan
和guid
)。 因此,在将dynamic
值序列化为 JSON 表示形式时,JSON 无法表示的值将被序列化为string
值。 与之相反,Kusto 会将字符串作为强类型值进行分析(如果它们可以这样进行分析)。 这适用于datetime
、real
、long
和guid
类型。 有关 JSON 对象模型的详细信息,请参阅 json.org。 - Kusto 不会尝试保留属性包中从名称到值的映射的顺序,因此你不能假定顺序会保留。 例如,将两个具有相同映射集的属性包表示为
string
值时,它们完全有可能产生不同的结果。
动态文本
若要指定 dynamic
文本,请使用以下语法选项之一:
语法 | 说明 | 示例 |
---|---|---|
dynamic([ value [, ...]]) |
由动态文本或其他标量文本构成的数组。 | dynamic([1, 2, "hello"]) |
dynamic({ key = value [, ...]}) |
一个属性包,或对象。 键的值可以是嵌套属性包。 | dynamic({"a":1, "b":{"a":2}}) |
dynamic( value) |
一个动态值,其中包含内部标量数据类型的值。 | dynamic(4) |
dynamic(null) |
表示 null 值。 |
详细了解语法约定。
动态对象访问器
若要对字典执行下标操作,请使用点表示法 (dict.key
) 或方括号表示法 (dict["key"]
)。 如果下标为字符串常量,则这两个选项是等效的。
注意
若要使用表达式作为下标,请使用方括号表示法。 使用算术表达式时,方括号内的表达式必须括在圆括号中。
在下面的示例中,dict
和 arr
是 dynamic 类型的列:
表达式 | 访问器表达式类型 | 含义 | 注释 |
---|---|---|---|
dict[col] | 实体名称(列) | 使用 col 列的值作为键对字典执行下标操作 |
列必须为字符串类型 |
arr[index] | 实体索引(列) | 使用 index 列的值作为索引对数组执行下标操作 |
列必须为整数或布尔类型 |
arr[-index] | 实体索引(列) | 从数组末尾检索 'index'-th 值 | 列必须为整数或布尔类型 |
arr[(-1)] | 实体索引 | 检索数组中的最后一个值 | |
arr[toint(indexAsString)] | 函数调用 | 将 indexAsString 列的值强制转换为 int,并使用它们对数组执行下标操作 |
|
dict[['where']] | 用作实体名称(列)的关键字 | 使用 where 列的值作为键对字典执行下标操作 |
与某些查询语言关键字相同的实体名称必须用引号引起来 |
dict.['where'] 或 dict['where'] | 常数 | 使用 where 字符串作为键对字典执行下标操作 |
提示
建议尽可能使用常数下标。
即使子对象具有不同的基础类型,访问 dynamic
值的子对象也会产生另一个 dynamic
值。 可以使用 gettype
函数查明值的实际基础类型,并使用下面列出的任何类型强制转换函数将其强制转换为实际类型。
强制转换动态对象
对动态对象执行下标操作之后,必须将值强制转换为简单类型。
表达式 | 值 | 类型 |
---|---|---|
X | parse_json('[100,101,102]') | array |
X[0] | parse_json('100') | dynamic |
toint(X[1]) | 101 | int |
Y | parse_json('{"a1":100, "a b c":"2015-01-01"}') | dictionary |
Y.a1 | parse_json('100') | dynamic |
Y["a b c"] | parse_json("2015-01-01") | dynamic |
todate(Y["a b c"]) | datetime(2015-01-01) | datetime |
强制转换函数包括:
tolong()
todouble()
todatetime()
totimespan()
tostring()
toguid()
parse_json()
生成动态对象
可以使用多个函数创建新的 dynamic
对象:
- bag_pack() 通过名称/值对创建属性包。
- pack_array() 基于值列表(可以是列的列表,对于每一行,它将基于指定的列创建一个数组)创建一个数组。
- range() 创建一个包含数字算术序列的数组。
- zip() 将两个数组中的“并行”值配对成一个数组。
- repeat() 创建一个包含重复值的数组。
此外,还有多个聚合函数可用于创建 dynamic
数组来保存聚合值:
- buildschema() 返回包含多个
dynamic
值的聚合架构。 - make_bag() 返回一个在组内包含动态值的属性包。
- make_bag_if() 返回一个在组内包含动态值的属性包(带谓词)。
- make_list() 返回一个按顺序保存所有值的数组。
- make_list_if() 返回一个按顺序保存所有值的数组(带谓词)。
- make_list_with_nulls() 返回一个按顺序保存所有值(包括 NULL 值)的数组。
- make_set() 返回一个保存所有唯一值的数组。
- make_set_if() 返回一个保存所有唯一值的数组(带谓词)。
基于 dynamic 类型的运算符和函数
有关标量动态/数组函数的完整列表,请参阅动态/数组函数。
运算符或函数 | dynamic 数据类型的用法 |
---|---|
value in array |
如果有 = = value 的 array 元素,则为 true where City in ('London', 'Paris', 'Rome') |
value !in array |
如果没有 = = value 的 array 元素,则为 true |
array | 如果不是数组,则为 null |
bag_has_key( bag, key) |
检查动态包列是否包含给定密钥。 |
bag_keys( bag) |
枚举 dynamic 属性包对象中的所有根键。 |
bag_merge( bag1,...,bagN) |
将多个 dynamic 属性包合并成一个包含所有属性的 dynamic 属性包。 |
bag_set_key( bag,key,value) |
将动态属性包中的给定键设置为给定值。 |
extract_json (path,object), extract_json( path,object) |
使用路径导航到对象。 |
parse_json( source) |
将 JSON 字符串转换为动态对象。 |
range( from,to,step) |
一个 值数组。 |
mv-expand listColumn |
为指定单元格列表中的每个值复制一行。 |
summarize buildschema( column) |
根据列内容推断类型架构。 |
summarize make_bag( column) |
将列中的属性包(字典)值合并成一个属性包,无需进行键复制。 |
summarize make_bag_if( column,predicate) |
将列中的属性包(字典)值合并成一个属性包,无需进行键复制(带谓词)。 |
summarize make_list( column) |
平展行组并将列的值放入数组。 |
summarize make_list_if( column,predicate) |
平展行组并将列的值放入数组中(带谓词)。 |
summarize make_list_with_nulls( column) |
平展行组并将列的值(包括 NULL 值)放入数组中。 |
summarize make_set( column) |
平展行组并将列的值放入数组,不进行复制。 |
动态数据的索引编制
在数据引入期间,每个字段都被索引。 索引范围为单个数据分片。
若要为动态列编制索引,引入过程会枚举动态值中的所有“原子”元素(属性名、值、数组元素),并将它们转发给索引生成器。 否则,动态字段与字符串字段具有相同的倒排词索引。
示例
动态属性包
以下查询创建动态属性包。
print o=dynamic({"a":123, "b":"hello", "c":[1,2,3], "d":{}})
| extend a=o.a, b=o.b, c=o.c, d=o.d
为方便起见,还可以让查询文本自身中出现的 dynamic
文本包含以下类型的其他 Kusto 文本:datetime
、timespan
、real
、long
、guid
、bool
和 dynamic
。
在分析字符串时(例如在使用 parse_json
函数或引入数据时),此基于 JSON 的扩展不可用,但可以通过它执行以下操作:
print d=dynamic({"a": datetime(1970-05-11)})
若要将遵循 JSON 编码规则的 string
值分析为 dynamic
值,请使用 parse_json
函数。 例如:
parse_json('[43, 21, 65]')
- 数字数组parse_json('{"name":"Alan", "age":21, "address":{"street":432,"postcode":"JLK32P"}}')
- 字典parse_json('21')
- 包含数字的动态类型的单个值parse_json('"21"')
- 包含字符串的动态类型的单个值parse_json('{"a":123, "b":"hello", "c":[1,2,3], "d":{}}')
- 提供与上例中的o
相同的值。
注意
与 JavaScript 不同,JSON 要求使用双引号 ("
) 字符括住字符串和属性包属性名称。 因此,使用单引号 ('
) 字符括住 JSON 编码的字符串文本通常更简单。
将数据引入动态列
以下示例展示了如何定义一个保存 dynamic
列(以及 datetime
列)的表,然后将单个记录引入其中。 它还演示了如何对 CSV 文件中的 JSON 字符串进行编码。
// dynamic is just like any other type:
.create table Logs (Timestamp:datetime, Trace:dynamic)
// Everything between the "[" and "]" is parsed as a CSV line would be:
// 1. Since the JSON string includes double-quotes and commas (two characters
// that have a special meaning in CSV), we must CSV-quote the entire second field.
// 2. CSV-quoting means adding double-quotes (") at the immediate beginning and end
// of the field (no spaces allowed before the first double-quote or after the second
// double-quote!)
// 3. CSV-quoting also means doubling-up every instance of a double-quotes within
// the contents.
.ingest inline into table Logs
[2015-01-01,"{""EventType"":""Demo"", ""EventValue"":""Double-quote love!""}"]
输出
Timestamp | 跟踪 |
---|---|
2015-01-01 00:00:00.0000000 | {"EventType":"Demo","EventValue":"Double-quote love!"} |
相关内容
- 有关如何使用动态对象和对象访问器查询的示例,请参阅将值从一个集映射到另一个集。