operatore mv - expand
Espande gli array dinamici a più valori o i bag di proprietà in più record.
mv-expand può essere descritto come l'opposto degli operatori di aggregazione che impacchettano più valori in una singola serie di proprietà o array di tipo dinamico, come summarize ... make-list() e make-series. Ogni elemento nell'array (scalare) o nel contenitore delle proprietà genera un nuovo record nell'output dell'operatore. Tutte le colonne dell'input che non sono espanse vengono duplicate in tutti i record nell'output.
Sintassi
A | mv-expand [bagexpansion=(bag | array)] [with_itemindex=IndexColumnName] ColumnName [to typeof( Typename)] [, ColumnName ...] [limit Rowlimit]
T | mv-expand [bagexpansion=(bag | array)] Nome = ArrayExpression [to typeof(Nome tipo)] [, [Nome =] ArrayExpression [to typeof(Nome tipo)] ...] [limit Limite riga]
Argomenti
ColumnName, ArrayExpression: un riferimento di colonna o un'espressione scalare, con un valore di tipo
dynamic, che contiene un array o un contenitore di proprietà. I singoli elementi di livello superiore dell'array o del contenitore di proprietà vengono espansi in più record.
Quando si utilizza ArrayExpression e Name non è uguale ad alcun nome di colonna di input, il valore espanso viene esteso in una nuova colonna nell'output. Altrimenti, il ColumnName esistente viene sostituito.Nome : un nome per la nuova colonna.
Nome tipo: indica il tipo sottostante degli elementi dell'array, che diventa il tipo della colonna prodotta dall'operatore
mv-expand. L'operazione di applicazione del tipo è solo cast e non include l'analisi o la conversione del tipo. Gli elementi dell'array che non sono conformi al tipo dichiarato diventeranno valorinull.RowLimit: il numero massimo di righe generate da ciascuna riga originale. Il valore predefinito è 2147483647.
IndexColumnNome: Se si specifica
with_itemindex, l'output includerà un'altra colonna (denominata IndexColumnName), che contiene l'indice (a partire da 0) dell'elemento della raccolta espansa originale.
Restituisce
Per ogni record nell'input, l'operatore restituisce zero, uno o più record nell'output, come determinato nel seguente modo:
Le colonne di input non espanse vengono visualizzate nell'output con il valore originale. Se un singolo record di input viene espanso in più record di output, il valore viene duplicato in tutti i record.
Per ogni ColumnName o ArrayExpression espansa, il numero di record di output viene determinato per ciascun valore come spiegato sotto. Per ogni record di input, viene calcolato il numero massimo di record di output. Tutti gli array o i bag di proprietà vengono espansi "in parallelo" in modo che i valori mancanti (se presenti) vengano sostituiti da valori null. Gli elementi vengono espansi in righe nell'ordine in cui appaiono nell'array/bag originale.
Se il valore dinamico è null, viene prodotto un singolo record per tale valore (null). Se il valore dinamico è un array vuoto o un contenitore di proprietà, non viene prodotto alcun record per tale valore. Altrimenti, vengono prodotti tanti record quanti sono gli elementi nel valore dinamico.
Le colonne espanse sono di tipo dynamic, a meno che non vengano immesse esplicitamente utilizzando la clausola to typeof() .
Modalità di espansione
Sono supportate due modalità di espansione del contenitore delle proprietà:
bagexpansion=bagokind=bag: i contenitori di proprietà vengono espansi in contenitori di proprietà a immissione singola. Questa è la modalità predefinita.bagexpansion=arrayokind=array: i bag di proprietà vengono espansi in strutture di array[chiave,valore]a due elementi, consentendo un accesso uniforme a chiavi e valori. Questa modalità consente anche, ad esempio, l'esecuzione di un'aggregazione di conteggio distinto sui nomi delle proprietà.
Esempi
Colonna singola
Una semplice espansione di una singola colonna:
events
| project severity, name, ipv4_addrs=ipv4_addr___value, ipv4_addrs_ctx=ipv4_addr___context,
original_time=unixtime_milliseconds_todatetime(original_time),
src_ip=network_traffic___x_src_ipv4_value[0],
dst_ip=network_traffic___x_dst_ipv4_value[0]
| where original_time > ago(24h) and src_ip != dst_ip
| take 2 // Only take 2 rows to expand
| mv-expand with_itemindex=idx ipv4_addrs, ipv4_addrs_ctx
| project idx, name, ipv4_addrs, ipv4_addrs_ctx
datatable (a:int, b:dynamic)[1,dynamic({"prop1":"a", "prop2":"b"})]
| mv-expand b
Risultati
| a | b |
|---|---|
| 1 | {"prop1":"a"} |
| 1 | {"prop2":"b"} |
Due colonne con zip
L'espansione di due colonne prima 'comprime' le colonne applicabili e quindi le espande:
datatable (a:int, b:dynamic, c:dynamic)[1,dynamic({"prop1":"a", "prop2":"b"}), dynamic([5, 4, 3])]
| mv-expand b, c
Risultati
| a | b | c |
|---|---|---|
| 1 | {"prop1":"a"} | 5 |
| 1 | {"prop2":"b"} | 4 |
| 1 | 3 |
Prodotto cartesiano di due colonne
Se si desidera ottenere un prodotto cartesiano di espansione di due colonne, espandere uno dopo l'altro:
datatable (a:int, b:dynamic, c:dynamic)
[
1,
dynamic({"prop1":"a", "prop2":"b"}),
dynamic([5, 6])
]
| mv-expand b
| mv-expand c
Risultati
| a | b | c |
|---|---|---|
| 1 | { "prop1": "a"} | 5 |
| 1 | { "prop1": "a"} | 6 |
| 1 | { "prop2": "b"} | 5 |
| 1 | { "prop2": "b"} | 6 |
Converti output
Per forzare l'output di un mv - expand a un determinato tipo (il valore predefinito è dinamico), utilizzare 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
Risultati
| ColumnName | ColumnOrdinal | DateType | ColumnType |
|---|---|---|---|
| a | 0 | System.String | stringa |
| b | 1 | System.Object | dinamico |
| c | 2 | System.Int32 | INT |
La colonna di avviso b viene restituita come dynamic mentre c viene restituita come int.
Utilizzo di with_itemindex
Espansione di un array con with_itemindex:
range x from 1 to 4 step 1
| summarize x = make_list(x)
| mv-expand with_itemindex=Index x
Risultati
| x | Indice |
|---|---|
| 1 | 0 |
| 2 | 1 |
| 3 | 2 |
| 4 | 3 |