(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Cómo expandir arrays con mv-expand en KQL: ejemplo

João Barros 12 de July de 2026 5 min de lectura

En las tablas de telemetría es muy habitual encontrar columnas dinámicas que guardan listas dentro de una sola celda: etiquetas de un evento, IDs de productos de un pedido, códigos de error. Expandir arrays con mv-expand en KQL convierte cada valor de esa lista en una fila propia, y eso es lo que permite después filtrar, agrupar y contar como en cualquier tabla normal. Todos los ejemplos siguientes se pueden copiar tal cual en un KQL Queryset, porque crean los datos en memoria.

Requisitos previos

  • Acceso a una base de datos KQL (Eventhouse en Microsoft Fabric) o a un clúster de Azure Data Explorer.
  • Un KQL Queryset o la Web UI de Kusto para escribir consultas.
  • Nociones básicas de los operadores where, project y summarize.
  • No hace falta cargar datos: usamos el operador datatable para crear tablas de ejemplo.

Paso 1: Crear datos de ejemplo con datatable

Antes de expandir arrays en KQL, necesitamos una tabla con una columna de tipo dynamic. El operador datatable crea una tabla temporal sin tocar la base de datos: perfecto para aprender y probar.

let Eventos = datatable(id:int, utilizador:string, etiquetas:dynamic)
[
    1, "ana",   dynamic(["bi", "fabric"]),
    2, "rui",   dynamic(["kql"]),
    3, "maria", dynamic(["bi", "kql", "azure"])
];
Eventos

El resultado tiene 3 filas. Fíjese en que la columna etiquetas muestra la lista entera en una sola celda, y por eso todavía no podemos contar cuántas veces aparece cada etiqueta.

Paso 2: Expandir el array con mv-expand

El operador mv-expand (multi-value expand) toma una columna dinámica y produce una fila por cada elemento del array. Las demás columnas de la fila original se repiten en cada fila nueva.

Eventos
| mv-expand etiquetas

Ahora tenemos 6 filas: 2 para "ana", 1 para "rui" y 3 para "maria". La columna etiquetas ya no contiene una lista, sino un único valor por fila.

Paso 3: Dar nombre y tipo al valor expandido

Por defecto, el valor expandido sigue siendo de tipo dynamic, lo que estorba en comparaciones de texto y ordenaciones. La buena práctica es asignar un nombre nuevo a la columna y convertir el tipo con to typeof().

Eventos
| mv-expand etiqueta = etiquetas to typeof(string)
| project id, utilizador, etiqueta

La columna etiqueta es ahora una string de verdad. Eso permite escribir, por ejemplo, | where etiqueta == "kql" sin sorpresas.

Paso 4: Conocer la posición de cada valor con with_itemindex

A veces el orden dentro del array tiene significado (el primer error, la categoría principal). La opción with_itemindex devuelve el índice de cada elemento, empezando en 0.

Eventos
| mv-expand with_itemindex = posicao etiqueta = etiquetas to typeof(string)
| project id, utilizador, posicao, etiqueta
| where posicao == 0

Este ejemplo devuelve solo la primera etiqueta de cada evento: una forma sencilla de extraer el valor principal de una lista.

Paso 5: Expandir un diccionario (property bag)

Una columna dynamic también puede guardar un objeto con pares clave/valor. Con kind=array, cada par se expande a un pequeño array de dos elementos: en la posición 0 queda la clave y en la posición 1 el valor.

let Propriedades = datatable(id:int, props:dynamic)
[
    1, dynamic({"pais": "PT", "plano": "pro"}),
    2, dynamic({"pais": "ES", "plano": "free"})
];
Propriedades
| mv-expand kind = array props
| extend chave = tostring(props[0]), valor = tostring(props[1])
| project id, chave, valor

El resultado es una tabla larga y estrecha, con una fila por propiedad: el formato ideal para pivotar o filtrar por clave más adelante.

Paso 6: Agregar después de expandir

Con el array expandido, summarize vuelve a ser trivial. Este es el objetivo real de la mayoría de las consultas con mv-expand en KQL: contar cuántas veces aparece cada valor.

Eventos
| mv-expand etiqueta = etiquetas to typeof(string)
| summarize eventos = count() by etiqueta
| order by eventos desc

Debe obtener bi y kql con 2 eventos cada uno, y fabric y azure con 1.

Error habitual: si la columna es texto (por ejemplo, un JSON guardado como string), mv-expand no la puede expandir. Conviértala primero con extend lista = todynamic(coluna_texto) y solo después expándala.

Verificar el resultado

Compruebe tres cosas. Primero, el número de filas: Eventos | mv-expand etiquetas | count debe devolver 6, es decir, la suma de los tamaños de todos los arrays. Segundo, el tipo de la columna: añada | extend t = gettype(etiqueta) y confirme que aparece string (y no array). Tercero, si trabaja con arrays muy grandes, tenga en cuenta que mv-expand expande hasta 2048 valores por fila de forma predeterminada; puede ajustar ese máximo con la opción limit.

Conclusión

Con mv-expand, to typeof() y with_itemindex ya puede convertir cualquier columna dinámica en una tabla plana lista para agregar. El paso natural siguiente es mv-apply, que expande el array, aplica una subconsulta a cada elemento y vuelve a agregar: muy útil, por ejemplo, para quedarse solo con el valor más alto de cada lista. Un consejo final: expanda lo más tarde posible en la consulta, después de los where, porque la expansión multiplica filas y es ahí donde se pierde el rendimiento. ¿Qué columnas dinámicas tiene en sus datos esperando a ser expandidas?