dynamic 数据类型The dynamic data type

dynamic 标量数据类型很特殊,因为它可以接受以下列表中的其他标量数据类型以及数组和属性包的任何值。The dynamic scalar data type is special in that it can take on any value of other scalar data types from the list below, as well as arrays and property bags. 具体而言,dynamic 值可以是:Specifically, a dynamic value can be:

  • NULL。Null.
  • 下述任何基元标量数据类型的值:booldatetimeguidintlongrealstringtimespanA value of any of the primitive scalar data types: bool, datetime, guid, int, long, real, string, and timespan.
  • dynamic 值的数组,其中包含零个或零个以上的值,并从零开始编制索引。An array of dynamic values, holding zero or more values with zero-based indexing.
  • 一个属性包,可将唯一的 string 值映射到 dynamic 值。A property bag that maps unique string values to dynamic values. 此属性包有零个或零个以上的此类映射(称为“槽”),通过唯一的 string 值进行索引编制。The property bag has zero or more such mappings (called "slots"), indexed by the unique string values. 这些槽是无序的。The slots are unordered.

备注

  • dynamic 类型的值的限制为 1MB (2^20)。Values of type dynamic are limited to 1MB (2^20).
  • 虽然 dynamic 类型看起来类似于 JSON,但是它可以保存 JSON 模型无法表示的不存在于 JSON 中的值(例如,longrealdatetimetimespanguid)。Although the dynamic type appears JSON-like, it can hold values that the JSON model does not represent because they don't exist in JSON (e.g., long, real, datetime, timespan, and guid). 因此,在将 dynamic 值序列化为 JSON 表示形式时,JSON 无法表示的值将被序列化为 string 值。Therefore, in serializing dynamic values into a JSON representation, values that JSON can't represent are serialized into string values. 与之相反,Kusto 会将字符串作为强类型值进行分析(如果它们可以这样进行分析)。Conversely, Kusto will parse strings as strongly-typed values if they can be parsed as such. 这适用于 datetimereallongguid 类型。This applies for datetime, real, long, and guid types. 有关 JSON 对象模型的详细信息,请参阅 json.orgFor more about the JSON object model, see json.org.
  • Kusto 不会尝试保留属性包中从名称到值的映射的顺序,因此你不能假定顺序会保留。Kusto doesn't attempt to preserve the order of name-to-value mappings in a property bag, and so you can't assume the order to be preserved. 例如,将两个具有相同映射集的属性包表示为 string 值时,它们完全有可能产生不同的结果。It's entirely possible for two property bags with the same set of mappings to yield different results when they are represented as string values, for example.

动态文本Dynamic literals

类型为 dynamic 的文本如下所示:A literal of type dynamic looks like this:

dynamic( Value )dynamic( Value )

Value 可以是:Value can be:

  • null,在这种情况下,文本表示 null 动态值:dynamic(null)null, in which case the literal represents the null dynamic value: dynamic(null).
  • 另一种标量数据类型文本,在这种情况下,文本表示“内部”类型的 dynamic 文本。Another scalar data type literal, in which case the literal represents the dynamic literal of the "inner" type. 例如,dynamic(4) 是一个动态值,其中的值 4 为长标量数据类型。For example, dynamic(4) is a dynamic value holding the value 4 of the long scalar data type.
  • 动态文本或其他类型文本的数组:[ ListOfValues ]An array of dynamic or other literals: [ ListOfValues ]. 例如,dynamic([1, 2, "hello"]) 是由三个元素组成的动态数组,两个为 long 值,一个为 string 值。For example, dynamic([1, 2, "hello"]) is a dynamic array of three elements, two long values and one string value.
  • 属性包:{ Name = Value ... }A property bag: { Name = Value ... }. 例如,dynamic({"a":1, "b":{"a":2}}) 是具有两个槽(ab)的属性包,第二个槽是另一个属性包。For example, dynamic({"a":1, "b":{"a":2}}) is a property bag with two slots, a, and b, with the second slot being another property bag.
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 文本:datetimetimespanreallongguidbooldynamicFor convenience, dynamic literals that appear in the query text itself may also include other Kusto literals with types: datetime, timespan, real, long, guid, bool, and dynamic. 在分析字符串时(例如在使用 parse_json 函数或引入数据时),此基于 JSON 的扩展不可用,但可以通过它执行以下操作:This extension over JSON isn't available when parsing strings (such as when using the parse_json function or when ingesting data), but it enables you to do the following:

print d=dynamic({"a": datetime(1970-05-11)})

若要将遵循 JSON 编码规则的 string 值分析为 dynamic 值,请使用 parse_json 函数。To parse a string value that follows the JSON encoding rules into a dynamic value, use the parse_json function. 例如:For example:

  • parse_json('[43, 21, 65]') - 数字数组parse_json('[43, 21, 65]') - an array of numbers
  • parse_json('{"name":"Alan", "age":21, "address":{"street":432,"postcode":"JLK32P"}}') - 字典parse_json('{"name":"Alan", "age":21, "address":{"street":432,"postcode":"JLK32P"}}') - a dictionary
  • parse_json('21') - 包含数字的动态类型的单个值parse_json('21') - a single value of dynamic type containing a number
  • parse_json('"21"') - 包含字符串的动态类型的单个值parse_json('"21"') - a single value of dynamic type containing a string
  • parse_json('{"a":123, "b":"hello", "c":[1,2,3], "d":{}}') - 提供与上例中的 o 相同的值。parse_json('{"a":123, "b":"hello", "c":[1,2,3], "d":{}}') - gives the same value as o in the example above.

备注

与 JavaScript 不同,JSON 要求使用双引号 (") 字符括住字符串和属性包属性名称。Unlike JavaScript, JSON mandates the use of double-quote (") characters around strings and property-bag property names. 因此,使用单引号 (') 字符括住 JSON 编码的字符串文本通常更简单。Therefore, it is generally easier to quote a JSON-encoded string literal by using a single-quote (') character.

以下示例展示了如何定义一个保存 dynamic 列(以及 datetime 列)的表,然后将单个记录引入其中。The following example shows how you can define a table that holds a dynamic column (as well as a datetime column) and then ingest into it a single record. 它还演示了如何对 CSV 文件中的 JSON 字符串进行编码:it also demonstrates how you can encode JSON strings in CSV files:

// 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!""}"]
TimestampTimestamp 跟踪Trace
2015-01-01 00:00:00.00000002015-01-01 00:00:00.0000000 {"EventType":"Demo","EventValue":"Double-quote love!"}{"EventType":"Demo","EventValue":"Double-quote love!"}

动态对象访问器Dynamic object accessors

若要对字典执行下标操作,请使用点表示法 (dict.key) 或方括号表示法 (dict["key"])。To subscript a dictionary, use either the dot notation (dict.key) or the brackets notation (dict["key"]). 如果下标为字符串常量,则这两个选项是等效的。When the subscript is a string constant, both options are equivalent.

备注

若要使用表达式作为下标,请使用方括号表示法。To use an expression as the subscript, use the brackets notation. 使用算术表达式时,方括号内的表达式必须括在圆括号中。When using arithmetic expressions, the expression inside the brackets must be wrapped in parentheses.

在下面的示例中,dictarr 是 dynamic 类型的列:In the examples below dict and arr are columns of dynamic type:

表达式Expression 访问器表达式类型Accessor expression type 含义Meaning 注释Comments
dict[col]dict[col] 实体名称(列)Entity name (column) 使用 col 列的值作为键对字典执行下标操作Subscripts a dictionary using the values of the column col as the key 列必须为字符串类型Column must be of type string
arr[index]arr[index] 实体索引(列)Entity index (column) 使用 index 列的值作为索引对数组执行下标操作Subscripts an array using the values of the column index as the index 列必须为整数或布尔类型Column must be of type integer or boolean
arr[-index]arr[-index] 实体索引(列)Entity index (column) 从数组末尾检索 'index'-th 值Retrieves the 'index'-th value from the end of the array 列必须为整数或布尔类型Column must be of type integer or boolean
arr[(-1)]arr[(-1)] 实体索引Entity index 检索数组中的最后一个值Retrieves the last value in the array
arr[toint(indexAsString)]arr[toint(indexAsString)] 函数调用Function call indexAsString 列的值强制转换为 int,并使用它们对数组执行下标操作Casts the values of column indexAsString to int and use them to subscript an array
dict[['where']]dict[['where']] 用作实体名称(列)的关键字Keyword used as entity name (column) 使用 where 列的值作为键对字典执行下标操作Subscripts a dictionary using the values of column where as the key 与某些查询语言关键字相同的实体名称必须用引号引起来Entity names that are identical to some query language keywords must be quoted
dict.['where'] 或 dict['where']dict.['where'] or dict['where'] 常数Constant 使用 where 字符串作为键对字典执行下标操作Subscripts a dictionary using where string as the key

性能提示: 尽可能使用常数下标Performance tip: Prefer to use constant subscripts when possible

即使子对象具有不同的基础类型,访问 dynamic 值的子对象也会产生另一个 dynamic 值。Accessing a sub-object of a dynamic value yields another dynamic value, even if the sub-object has a different underlying type. 可以使用 gettype 函数查明值的实际基础类型,并使用下面列出的任何类型强制转换函数将其强制转换为实际类型。Use the gettype function to discover the actual underlying type of the value, and any of the cast function listed below to cast it to the actual type.

强制转换动态对象Casting dynamic objects

对动态对象执行下标操作之后,必须将值强制转换为简单类型。After subscripting a dynamic object, you must cast the value to a simple type.

表达式Expression Value 类型Type
XX parse_json('[100,101,102]')parse_json('[100,101,102]') arrayarray
X[0]X[0] parse_json('100')parse_json('100') 动态dynamic
toint(X[1])toint(X[1]) 101101 intint
YY parse_json('{"a1":100, "a b c":"2015-01-01"}')parse_json('{"a1":100, "a b c":"2015-01-01"}') dictionarydictionary
Y.a1Y.a1 parse_json('100')parse_json('100') 动态dynamic
Y["a b c"]Y["a b c"] parse_json("2015-01-01")parse_json("2015-01-01") 动态dynamic
todate(Y["a b c"])todate(Y["a b c"]) datetime(2015-01-01)datetime(2015-01-01) datetimedatetime

强制转换函数包括:Cast functions are:

  • tolong()
  • todouble()
  • todatetime()
  • totimespan()
  • tostring()
  • toguid()
  • todynamic()

生成动态对象Building dynamic objects

可以使用多个函数创建新的 dynamic 对象:Several functions enable you to create new dynamic objects:

  • pack() 通过名称/值对创建属性包。pack() creates a property bag from name/value pairs.
  • pack_array() 通过名称/值对创建数组。pack_array() creates an array from name/value pairs.
  • range() 创建一个包含数字算术序列的数组。range() creates an array with an arithmetic series of numbers.
  • zip() 将两个数组中的“并行”值配对成一个数组。zip() pairs "parallel" values from two arrays into a single array.
  • repeat() 创建一个包含重复值的数组。repeat() creates an array with a repeated value.

此外,还有多个聚合函数可用于创建 dynamic 数组来保存聚合值:Additionally, there are several aggregate functions which create dynamic arrays to hold aggregated values:

  • buildschema() 返回包含多个 dynamic 值的聚合架构。buildschema() returns the aggregate schema of multiple dynamic values.
  • make_bag() 返回一个在组内包含动态值的属性包。make_bag() returns a property bag of dynamic values within the group.
  • make_bag_if() 返回一个在组内包含动态值的属性包(带谓词)。make_bag_if() returns a property bag of dynamic values within the group (with a predicate).
  • make_list() 返回一个按顺序保存所有值的数组。make_list() returns an array holding all values, in sequence.
  • make_list_if() 返回一个按顺序保存所有值的数组(带谓词)。make_list_if() returns an array holding all values, in sequence (with a predicate).
  • make_list_with_nulls() 返回一个按顺序保存所有值(包括 NULL 值)的数组。make_list_with_nulls() returns an array holding all values, in sequence, including null values.
  • make_set() 返回一个保存所有唯一值的数组。make_set() returns an array holding all unique values.
  • make_set_if() 返回一个保存所有唯一值的数组(带谓词)。make_set_if() returns an array holding all unique values (with a predicate).

基于 dynamic 类型的运算符和函数Operators and functions over dynamic types

运算符或函数Operator or function dynamic 数据类型的用法Usage with dynamic data types
value in arrayvalue in array 如果有 = = valuearray 元素,则为 trueTrue if there is an element of array that == value
where City in ('London', 'Paris', 'Rome')
value !in arrayvalue !in array 如果没有 == valuearray 元素,则为 trueTrue if there is no element of array that == value
arrayarray_length(``)array_length(array) 如果不是数组,则为 nullNull if it isn't an array
bag_keys(bag)bag_keys(bag) 枚举 dynamic 属性包对象中的所有根键。Enumerates all the root keys in a dynamic property-bag object.
bag_merge(bag1,...,bagN)bag_merge(bag1,...,bagN) 将多个 dynamic 属性包合并成一个包含所有属性的 dynamic 属性包。Merges dynamic property-bags into a dynamic property-bag with all properties merged.
extractjson(path,object)extractjson(path,object) 使用路径导航到对象。Uses path to navigate into object.
parse_json(source)parse_json(source) 将 JSON 字符串转换为动态对象。Turns a JSON string into a dynamic object.
range(from,to,step)range(from,to,step) 值组成的数组An array of values
mv-expand listColumnmv-expand listColumn 为指定单元格列表中的每个值复制一行。Replicates a row for each value in a list in a specified cell.
summarize buildschema(column)summarize buildschema(column) 根据列内容推断类型架构Infers the type schema from column content
summarize make_bag(column)summarize make_bag(column) 将列中的属性包(字典)值合并成一个属性包,无需进行键复制。Merges the property bag (dictionary) values in the column into one property bag, without key duplication.
summarize make_bag_if(column,predicate)summarize make_bag_if(column,predicate) 将列中的属性包(字典)值合并成一个属性包,无需进行键复制(带谓词)。Merges the property bag (dictionary) values in the column into one property bag, without key duplication (with predicate).
summarize make_list(column) summarize make_list(column) 平展行组并将列的值放入数组。Flattens groups of rows and puts the values of the column in an array.
summarize make_list_if(column,predicate) summarize make_list_if(column,predicate) 平展行组并将列的值放入数组中(带谓词)。Flattens groups of rows and puts the values of the column in an array (with predicate).
summarize make_list_with_nulls(column) summarize make_list_with_nulls(column) 平展行组并将列的值(包括 NULL 值)放入数组中。Flattens groups of rows and puts the values of the column in an array, including null values.
summarize make_set(column)summarize make_set(column) 平展行组并将列的值放入数组,不进行复制。Flattens groups of rows and puts the values of the column in an array, without duplication.