Оператор mv-expand

Развертывает динамические массивы с несколькими значениями или контейнеры свойств в несколько записей.

mv-expand можно описать как противоположность операторам агрегирования, которые упаковывают множество значений в один массив или контейнер свойств динамического типа, например summarize ... make-list() и make-series. Каждый элемент в (скалярном) массиве или контейнере свойств создает новую запись в выходных данных оператора. Все неразвернутые столбцы входных данных дублируются для всех записей в выходных данных.

Синтаксис

T|mv-expand [kind=(bagarray | )] [with_itemindex=IndexColumnName] ColumnName [to typeof(Typename)] [,ColumnName ...] [limitRowlimit]

T|mv-expand [kind=(bagarray | )] [Имя=] ArrayExpression [to typeof(Typename)] [, [Name=] ArrayExpression [to typeof(Typename)] ...] [limitRowlimit]

Дополнительные сведения о соглашениях о синтаксисе.

Параметры

Имя Тип Обязательно Описание
ColumnName, ArrayExpression string ✔️ Ссылка на столбец или скалярное выражение со значением типа dynamic , которое содержит массив или контейнер свойств. Отдельные элементы верхнего уровня в массиве или контейнере свойств развертываются в несколько записей.
Если используется ArrayExpression, а Name не совпадает с именем столбца входных данных, развернутое значение расширяется в новый столбец в выходных данных. В противном случае заменяется существующее значение ColumnName.
имя; string Имя нового столбца.
Typename string ✔️ Указывает базовый тип элементов массива, который становится типом столбца, созданного оператором mv-expand . Операция применения типа предназначена только для приведения и не включает синтаксический анализ или преобразование типа. Элементы массива, которые не соответствуют объявленному типу, становятся значениями null .
RowLimit int Максимальное число строк, созданных из каждой исходной строки. Значение по умолчанию — 2147483647. mvexpand является прежней версией и устаревшей формой оператора mv-expand. В прежней версии по умолчанию используется ограничение в 128 строк.
IndexColumnName string Если with_itemindex указан параметр , выходные данные включают другой столбец с именем IndexColumnName , содержащий индекс, начинающийся с 0 элемента в исходной развернутой коллекции.

Возвращаемое значение

Для каждой записи во входных данных оператор возвращает в выходных данных нуль, одну или несколько записей в соответствии со следующим определением:

  1. Неразвернутые входные столбцы отображаются в выходных данных с исходными значениями. Если одна входная запись развертывается в несколько выходных записей, значение дублируется во всех записях.

  2. Для каждого развернутого объекта ColumnName или ArrayExpression определяется количество выходных записей для каждого значения, как описано в режимах расширения. Для каждой входной записи вычисляется максимальное число выходных записей. Все массивы или контейнеры свойств развертываются параллельно, чтобы отсутствующие значения (если они есть) заменялись значениями NULL. Элементы развертываются в строки в том порядке, в котором они отображаются в исходном массиве или контейнере.

  3. Если динамическое значение равно NULL, то для этого значения создается одна запись (NULL). Если динамическое значение — пустой массив или контейнер свойств, запись для этого значения не создается. В противном случае создается количество записей, равное количеству элементов в динамическом значении.

Развернутые столбцы имеют тип dynamic, если тип не указан явно с помощью предложения to typeof().

Режимы развертывания

Поддерживаются два режима развертывания контейнера свойств.

  • kind=bag или bagexpansion=bag: контейнеры свойств развертываются в контейнеры свойств с одной записью. Этот режим используется по умолчанию.
  • kind=array или bagexpansion=array: контейнеры свойств развертываются в структуры массива с двумя элементами [key,value]. Это позволяет единообразно обращаться к ключам и значениям. Кроме того, этот режим позволяет выполнять, например, подсчет различных значений в именах свойств.

Примеры

Один столбец — расширение массива

datatable (a: int, b: dynamic)
[
    1, dynamic([10, 20]),
    2, dynamic(['a', 'b'])
]
| mv-expand b

Выходные данные

а b
1 10
1 20
2 а
2 b

Один столбец — расширение контейнера

Простое развертывание одного столбца:

datatable (a: int, b: dynamic)
[
    1, dynamic({"prop1": "a1", "prop2": "b1"}),
    2, dynamic({"prop1": "a2", "prop2": "b2"})
]
| mv-expand b

Выходные данные

а b
1 {"prop1": "a1"}
1 {"prop2": "b1"}
2 {"prop1": "a2"}
2 {"prop2": "b2"}

Один столбец — расширение контейнера до пар "ключ-значение"

Простое расширение контейнера до пар "ключ-значение":

datatable (a: int, b: dynamic)
[
    1, dynamic({"prop1": "a1", "prop2": "b1"}),
    2, dynamic({"prop1": "a2", "prop2": "b2"})
]
| mv-expand kind=array b 
| extend key = b[0], val=b[1]

Выходные данные

а b ключ Валь
1 ["prop1","a1"] prop1 a1
1 ["prop2","b1"] prop2 b1
2 ["prop1","a2"] prop1 a2
2 ["prop2","b2"] prop2 B2

Сжатые два столбца

При развертывании двух столбцов применимые столбцы сначала будут сжаты, а затем развернуты:

datatable (a: int, b: dynamic, c: dynamic)[
    1, dynamic({"prop1": "a", "prop2": "b"}), dynamic([5, 4, 3])
]
| mv-expand b, c

Выходные данные

а b с
1 {"prop1":"a"} 5
1 {"prop2":"b"} 4
1 3

Декартово произведение двух столбцов

Если вы хотите получить декартово произведение для развертывания двух столбцов, разверните по очереди:

datatable (a: int, b: dynamic, c: dynamic)
[
    1, dynamic({"prop1": "a", "prop2": "b"}), dynamic([5, 6])
]
| mv-expand b
| mv-expand c

Выходные данные

а b с
1 { "prop1": "a"} 5
1 { "prop1": "a"} 6
1 { "prop2": "b"} 5
1 { "prop2": "b"} 6

Преобразование вывода

Чтобы принудительно развернуть выходные данные mv-expand до определенного типа (по умолчанию — динамический), используйте to typeof:

datatable (a: string, b: dynamic, c: dynamic)[
    "Constant", dynamic([1, 2, 3, 4]), dynamic([6, 7, 8, 9])
]
| mv-expand b, c to typeof(int)
| getschema 

Выходные данные

ColumnName ColumnOrdinal DateType ColumnType
а 0 System.String string
b 1 System.Object dynamic
с 2 System.Int32 int

Обратите внимание: столбец b возвращается как столбец типа dynamic, а c — как столбец типа int.

Использование with_itemindex

Расширение массива с помощью with_itemindex:

range x from 1 to 4 step 1
| summarize x = make_list(x)
| mv-expand with_itemindex=Index x

Выходные данные

x Индекс
1 0
2 1
3 2
4 3