operatore scan
Si applica a: ✅Microsoft Fabric✅Azure Esplora dati✅ Azure Monitor✅Microsoft Sentinel
Analizza dati, corrispondenze e compila sequenze in base ai predicati.
I record corrispondenti vengono determinati in base ai predicati definiti nei passaggi dell'operatore. Un predicato può dipendere dallo stato generato dai passaggi precedenti. L'output per il record corrispondente è determinato dal record di input e dalle assegnazioni definite nei passaggi dell'operatore.
Sintassi
T | scan
[ with_match_id
=
MatchIdColumnName ] [ declare
(
ColumnDeclarations )
] with
(
StepDefinitions )
Sintassi columnDeclarations
ColumnName :
ColumnType[=
DefaultValue ] [,
... ]
Sintassi StepDefinition
step
StepName [ output
| none
all
last
= | ] :
Condition [ =>
Column =
Assignment [,
... ] ];
Altre informazioni sulle convenzioni di sintassi.
Parametri
Nome | Digita | Obbligatorio | Descrizione |
---|---|---|---|
T | string |
✔️ | Origine tabulare di input. |
MatchIdColumnName | string |
Nome di una colonna di tipo long aggiunta all'output come parte dell'esecuzione dell'analisi. Indica l'indice in base 0 della corrispondenza per il record. |
|
ColumnDeclarations | string |
Dichiara un'estensione allo schema di T. Queste colonne sono valori assegnati nei passaggi. Se non viene assegnato, viene restituito DefaultValue . Se non diversamente specificato, DefaultValue è null . |
|
StepName | string |
✔️ | Usato per fare riferimento ai valori nello stato di analisi per le condizioni e le assegnazioni. Il nome del passaggio deve essere univoco. |
Condizione | string |
✔️ | Espressione che restituisce true o false che definisce i record dell'input corrispondenti al passaggio. Un record corrisponde al passaggio quando la condizione è true con lo stato del passaggio o con lo stato del passaggio precedente. |
Assegnazione | string |
Espressione scalare assegnata alla colonna corrispondente quando un record corrisponde a un passaggio. | |
output |
string |
Controlla la logica di output del passaggio sulle corrispondenze ripetute. all restituisce tutti i record corrispondenti al passaggio, last restituisce solo l'ultimo record in una serie di corrispondenze ripetute per il passaggio e none non restituisce record corrispondenti al passaggio. Il valore predefinito è all . |
Valori restituiti
Record per ogni corrispondenza di un record dall'input a un passaggio. Lo schema dell'output è lo schema dell'origine estesa con la colonna nella declare
clausola .
Logica di analisi
scan
passa i dati di input serializzati, registra per record, confrontando ogni record con la condizione di ogni passaggio tenendo conto dello stato corrente di ogni passaggio.
Provincia
Lo stato sottostante dell'operatore scan
può essere considerato come una tabella con una riga per ogni step
. Ogni passaggio mantiene il proprio stato con i valori più recenti delle colonne e le variabili dichiarate da tutti i passaggi precedenti e il passaggio corrente. Se pertinente, contiene anche l'ID di corrispondenza per la sequenza in corso.
Se un operatore di analisi ha n passaggi denominati s_1, s_2, ..., s_n quindi il passaggio s_k avrà k record nello stato corrispondente a s_1, s_2, ..., s_k. StepName.Il formato ColumnName viene usato per fare riferimento a un valore nello stato . Ad esempio, s_2.col1
fare riferimento a una colonna col1
appartenente al passaggio s_2 nello stato di s_k. Per un esempio dettagliato, vedere la procedura dettagliata per la logica di analisi.
Lo stato inizia vuoto e viene aggiornato ogni volta che un record di input analizzato corrisponde a un passaggio. Quando lo stato del passaggio corrente non è vuoto, il passaggio viene definito con una sequenza attiva.
Logica di corrispondenza
Ogni record di input viene valutato rispetto a tutti i passaggi in ordine inverso, dall'ultimo passaggio al primo. Quando un record r viene valutato rispetto a un passaggio s_k, viene applicata la logica seguente:
Controllo 1: se lo stato del passaggio precedente (s_k-1) non èempty e r soddisfa la condizione di s_k, si verifica una corrispondenza. La corrispondenza porta alle azioni seguenti:
- Lo stato di s_k viene cancellato.
- Lo stato di s_k-1 viene promosso a diventare lo stato di s_k.
- Le assegnazioni di s_k vengono calcolate ed estese r.
- L'estensione r viene aggiunta all'output e allo stato di s_k.
Nota
Se il controllo 1 restituisce una corrispondenza, il controllo 2 viene ignorato e r passa a essere valutato rispetto a s_k-1.
Controllo 2: se lo stato di s_k ha una sequenza attiva o s_k è il primo passaggio e r soddisfa la condizione di s_k, si verifica una corrispondenza. La corrispondenza porta alle azioni seguenti:
- Le assegnazioni di s_k vengono calcolate ed estese r.
- I valori che rappresentano s_k nello stato di s_k vengono sostituiti con i valori dell'oggetto r esteso.
- Se s_k è definito come
output=all
, l'estensione r viene aggiunta all'output. - Se s_k è il primo passaggio, inizia una nuova sequenza e l'ID corrispondenza aumenta di
1
. Questo influisce solo sull'output quandowith_match_id
viene usato.
Una volta completati i controlli per s_k , r passa alla valutazione rispetto a s_k-1.
Per un esempio dettagliato di questa logica, vedere la procedura dettagliata per la logica di analisi.
Esempi
Somma cumulativa
Calcolare la somma cumulativa per una colonna di input. Il risultato di questo esempio equivale all'uso di row_cumsum().
range x from 1 to 5 step 1
| scan declare (cumulative_x:long=0) with
(
step s1: true => cumulative_x = x + s1.cumulative_x;
)
Output
x | cumulative_x |
---|---|
1 | 1 |
2 | 3 |
3 | 6 |
4 | 10 |
5 | 15 |
Somma cumulativa su più colonne con una condizione di reimpostazione
Calcolare la somma cumulativa per due colonne di input, reimpostare il valore della somma sul valore del record corrente ogni volta che la somma cumulativa ha raggiunto 10 o più.
range x from 1 to 5 step 1
| extend y = 2 * x
| scan declare (cumulative_x:long=0, cumulative_y:long=0) with
(
step s1: true => cumulative_x = iff(s1.cumulative_x >= 10, x, x + s1.cumulative_x),
cumulative_y = iff(s1.cumulative_y >= 10, y, y + s1.cumulative_y);
)
Output
x | y | cumulative_x | cumulative_y |
---|---|---|---|
1 | 2 | 1 | 2 |
2 | 4 | 3 | 6 |
3 | 6 | 6 | 12 |
4 | 8 | 10 | 8 |
5 | 10 | 5 | 18 |
Compilare una colonna
Compilare in avanti una colonna stringa. A ogni valore vuoto viene assegnato l'ultimo valore non vuoto visualizzato.
let Events = datatable (Ts: timespan, Event: string) [
0m, "A",
1m, "",
2m, "B",
3m, "",
4m, "",
6m, "C",
8m, "",
11m, "D",
12m, ""
]
;
Events
| sort by Ts asc
| scan declare (Event_filled: string="") with
(
step s1: true => Event_filled = iff(isempty(Event), s1.Event_filled, Event);
)
Output
Ts | Event | Event_filled |
---|---|---|
00:00:00 | Un | Un |
00:01:00 | Un | |
00:02:00 | G | G |
00:03:00 | G | |
00:04:00 | G | |
00:06:00 | A | A |
00:08:00 | A | |
00:11:00 | D | D |
00:12:00 | D |
Assegnazione di tag alle sessioni
Dividere l'input in sessioni: una sessione termina 30 minuti dopo il primo evento della sessione, dopo il quale viene avviata una nuova sessione. Si noti l'uso del with_match_id
flag, che assegna un valore univoco per ogni corrispondenza distinta (sessione) di analisi. Si noti anche l'uso speciale di due passaggi in questo esempio, ha true
come condizione in inSession
modo che acquisisca e restituisce tutti i record dall'input mentre endSession
acquisisce i record che si verificano più di 30 m dal valore per la sessionStart
corrispondenza corrente. Il endSession
passaggio ha output=none
un significato che non produce record di output. Il endSession
passaggio viene usato per far avanzare lo stato della corrispondenza corrente da inSession
a endSession
, consentendo l'inizio di una nuova corrispondenza (sessione), a partire dal record corrente.
let Events = datatable (Ts: timespan, Event: string) [
0m, "A",
1m, "A",
2m, "B",
3m, "D",
32m, "B",
36m, "C",
38m, "D",
41m, "E",
75m, "A"
]
;
Events
| sort by Ts asc
| scan with_match_id=session_id declare (sessionStart: timespan) with
(
step inSession: true => sessionStart = iff(isnull(inSession.sessionStart), Ts, inSession.sessionStart);
step endSession output=none: Ts - inSession.sessionStart > 30m;
)
Output
Ts | Event | sessionStart | session_id |
---|---|---|---|
00:00:00 | Un | 00:00:00 | 0 |
00:01:00 | Un | 00:00:00 | 0 |
00:02:00 | G | 00:00:00 | 0 |
00:03:00 | D | 00:00:00 | 0 |
00:32:00 | G | 00:32:00 | 1 |
00:36:00 | A | 00:32:00 | 1 |
00:38:00 | D | 00:32:00 | 1 |
00:41:00 | E | 00:32:00 | 1 |
01:15:00 | Un | 01:15:00 | 2 |
Eventi tra Start e Stop
Trovare tutte le sequenze di eventi tra l'evento Start
e l'evento Stop
che si verificano entro 5 minuti. Assegnare un ID di corrispondenza per ogni sequenza.
let Events = datatable (Ts: timespan, Event: string) [
0m, "A",
1m, "Start",
2m, "B",
3m, "D",
4m, "Stop",
6m, "C",
8m, "Start",
11m, "E",
12m, "Stop"
]
;
Events
| sort by Ts asc
| scan with_match_id=m_id with
(
step s1: Event == "Start";
step s2: Event != "Start" and Event != "Stop" and Ts - s1.Ts <= 5m;
step s3: Event == "Stop" and Ts - s1.Ts <= 5m;
)
Output
Ts | Event | m_id |
---|---|---|
00:01:00 | Inizio | 0 |
00:02:00 | G | 0 |
00:03:00 | D | 0 |
00:04:00 | Arresta | 0 |
00:08:00 | Inizio | 1 |
00:11:00 | E | 1 |
00:12:00 | Arresta | 1 |
Calcolare un imbuto personalizzato di eventi
Calcolare un completamento a imbuto della sequenza Hail
,Thunderstorm Wind
Tornado
>> con State
soglie personalizzate sui tempi tra gli eventi (Tornado
all'interno e Thunderstorm Wind
all'interno 1h
2h
di ). Questo esempio è simile al plug-in funnel_sequence_completion, ma consente una maggiore flessibilità.
StormEvents
| partition hint.strategy=native by State
(
sort by StartTime asc
| scan with
(
step hail: EventType == "Hail";
step tornado: EventType == "Tornado" and StartTime - hail.StartTime <= 1h;
step thunderstormWind: EventType == "Thunderstorm Wind" and StartTime - tornado.StartTime <= 2h;
)
)
| summarize dcount(State) by EventType
Output
EventType | dcount_State |
---|---|
Grandine | 50 |
Tornado | 34 |
Vento di tempesta | 32 |
Procedura dettagliata per la logica di analisi
Questa sezione illustra la logica di analisi usando una procedura dettagliata dell'esempio Eventi tra l'avvio e l'arresto:
let Events = datatable (Ts: timespan, Event: string) [
0m, "A",
1m, "Start",
2m, "B",
3m, "D",
4m, "Stop",
6m, "C",
8m, "Start",
11m, "E",
12m, "Stop"
]
;
Events
| sort by Ts asc
| scan with_match_id=m_id with
(
step s1: Event == "Start";
step s2: Event != "Start" and Event != "Stop" and Ts - s1.Ts <= 5m;
step s3: Event == "Stop" and Ts - s1.Ts <= 5m;
)
Stato
Si consideri lo stato dell'operatore scan
come una tabella con una riga per ogni passaggio, in cui ogni passaggio ha il proprio stato. Questo stato contiene i valori più recenti delle colonne e le variabili dichiarate da tutti i passaggi precedenti e dal passaggio corrente. Per altre informazioni, vedere State.To learn more, see State.
Per questo esempio, lo stato può essere rappresentato con la tabella seguente:
step | m_id | s1. Ts | s1. Evento | s2. Ts | s2. Evento | s3. Ts | s3. Evento |
---|---|---|---|---|---|---|---|
s1 | X | X | X | X | |||
s2 | X | X | |||||
s3 |
"X" indica che un campo specifico è irrilevante per tale passaggio.
Logica di corrispondenza
Questa sezione segue la logica di corrispondenza tramite ogni record della Events
tabella, spiegando la trasformazione dello stato e dell'output in ogni passaggio.
Nota
Un record di input viene valutato rispetto ai passaggi in ordine inverso, dall'ultimo passaggio (s3
) al primo passaggio (s1
).
Record 1
Ts | Event |
---|---|
0m | "A" |
Registrare la valutazione in ogni passaggio:
s3
: il controllo 1 non viene passato perché lo stato dis2
è vuoto e il controllo 2 non viene passato perchés3
manca una sequenza attiva.s2
: il controllo 1 non viene passato perché lo stato dis1
è vuoto e il controllo 2 non viene passato perchés2
manca una sequenza attiva.s1
: il controllo 1 è irrilevante perché non esiste alcun passaggio precedente. Il controllo 2 non viene passato perché il record non soddisfa la condizione diEvent == "Start"
. Il record 1 viene rimosso senza influire sullo stato o sull'output.
Stato:
step | m_id | s1. Ts | s1. Evento | s2. Ts | s2. Evento | s3. Ts | s3. Evento |
---|---|---|---|---|---|---|---|
s1 | X | X | X | X | |||
s2 | X | X | |||||
s3 |
Record 2
Ts | Event |
---|---|
1 min | "Start" |
Registrare la valutazione in ogni passaggio:
s3
: il controllo 1 non viene passato perché lo stato dis2
è vuoto e il controllo 2 non viene passato perchés3
manca una sequenza attiva.s2
: il controllo 1 non viene passato perché lo stato dis1
è vuoto e il controllo 2 non viene passato perchés2
manca una sequenza attiva.s1
: il controllo 1 è irrilevante perché non esiste alcun passaggio precedente. Il controllo 2 viene passato perché il record soddisfa la condizione diEvent == "Start"
. Questa corrispondenza avvia una nuova sequenza e l'oggettom_id
viene assegnato. Il record 2 e il relativom_id
(0
) vengono aggiunti allo stato e all'output.
Stato:
step | m_id | s1. Ts | s1. Evento | s2. Ts | s2. Evento | s3. Ts | s3. Evento |
---|---|---|---|---|---|---|---|
s1 | 0 | 00:01:00 | "Start" | X | X | X | X |
s2 | X | X | |||||
s3 |
Record 3
Ts | Event |
---|---|
2 min | "B" |
Registrare la valutazione in ogni passaggio:
s3
: il controllo 1 non viene passato perché lo stato dis2
è vuoto e il controllo 2 non viene passato perchés3
manca una sequenza attiva.s2
: il controllo 1 viene passato perché lo stato dis1
è nonempty e il record soddisfa la condizione diTs - s1.Ts < 5m
. Questa corrispondenza fa sì che lo stato dis1
venga cancellato e che la sequenza ins1
venga promossa as2
. Il record 3 e il relativom_id
(0
) vengono aggiunti allo stato e all'output.s1
: il controllo 1 è irrilevante perché non esiste alcun passaggio precedente e il controllo 2 non viene passato perché il record non soddisfa la condizione diEvent == "Start"
.
Stato:
step | m_id | s1. Ts | s1. Evento | s2. Ts | s2. Evento | s3. Ts | s3. Evento |
---|---|---|---|---|---|---|---|
s1 | X | X | X | X | |||
s2 | 0 | 00:01:00 | "Start" | 00:02:00 | "B" | X | X |
s3 |
Record 4
Ts | Event |
---|---|
3 min | "D" |
Registrare la valutazione in ogni passaggio:
s3
: il controllo 1 non viene passato perché il record non soddisfa la condizione diEvent == "Stop"
e il controllo 2 non viene passato perchés3
manca una sequenza attiva.s2
: il controllo 1 non viene passato perché lo stato dis1
è vuoto. passa il controllo 2 perché soddisfa la condizione diTs - s1.Ts < 5m
. Il record 4 e il relativom_id
(0
) vengono aggiunti allo stato e all'output. I valori di questo record sovrascrivono i valori di stato precedenti pers2.Ts
es2.Event
.s1
: il controllo 1 è irrilevante perché non esiste alcun passaggio precedente e il controllo 2 non viene passato perché il record non soddisfa la condizione diEvent == "Start"
.
Stato:
step | m_id | s1. Ts | s1. Evento | s2. Ts | s2. Evento | s3. Ts | s3. Evento |
---|---|---|---|---|---|---|---|
s1 | X | X | X | X | |||
s2 | 0 | 00:01:00 | "Start" | 00:03:00 | "D" | X | X |
s3 |
Record 5
Ts | Event |
---|---|
4 min | "Stop" |
Registrare la valutazione in ogni passaggio:
s3
: il controllo 1 viene passato perchés2
non èempty e soddisfa las3
condizione diEvent == "Stop"
. Questa corrispondenza fa sì che lo stato dis2
venga cancellato e che la sequenza ins2
venga promossa as3
. Il record 5 e il relativom_id
(0
) vengono aggiunti allo stato e all'output.s2
: il controllo 1 non viene passato perché lo stato dis1
è vuoto e il controllo 2 non viene passato perchés2
manca una sequenza attiva.s1
: il controllo 1 è irrilevante perché non esiste alcun passaggio precedente. Il controllo 2 non viene passato perché il record non soddisfa la condizione diEvent == "Start"
.
Stato:
step | m_id | s1. Ts | s1. Evento | s2. Ts | s2. Evento | s3. Ts | s3. Evento |
---|---|---|---|---|---|---|---|
s1 | X | X | X | X | |||
s2 | X | X | |||||
s3 | 0 | 00:01:00 | "Start" | 00:03:00 | "D" | 00:04:00 | "Stop" |
Record 6
Ts | Event |
---|---|
6 m | "C" |
Registrare la valutazione in ogni passaggio:
s3
: il controllo 1 non viene passato perché lo stato dis2
è vuoto e il controllo 2 non viene passato perchés3
non soddisfa las3
condizione diEvent == "Stop"
.s2
: il controllo 1 non viene passato perché lo stato dis1
è vuoto e il controllo 2 non viene passato perchés2
manca una sequenza attiva.s1
: il controllo 1 non viene passato perché non è presente alcun passaggio precedente e il controllo 2 non viene passato perché non soddisfa la condizione diEvent == "Start"
. Il record 6 viene rimosso senza influire sullo stato o sull'output.
Stato:
step | m_id | s1. Ts | s1. Evento | s2. Ts | s2. Evento | s3. Ts | s3. Evento |
---|---|---|---|---|---|---|---|
s1 | X | X | X | X | |||
s2 | X | X | |||||
s3 | 0 | 00:01:00 | "Start" | 00:03:00 | "D" | 00:04:00 | "Stop" |
Record 7
Ts | Event |
---|---|
8m | "Start" |
Registrare la valutazione in ogni passaggio:
s3
: il controllo 1 non viene passato perché lo stato dis2
è vuoto e il controllo 2 non viene passato perché non soddisfa la condizione diEvent == "Stop"
.s2
: il controllo 1 non viene passato perché lo stato dis1
è vuoto e il controllo 2 non viene passato perchés2
manca una sequenza attiva.s1
: il controllo 1 non viene passato perché non è presente alcun passaggio precedente. passa il controllo 2 perché soddisfa la condizione diEvent == "Start"
. Questa corrispondenza avvia una nuova sequenza ins1
con un nuovom_id
oggetto . Il record 7 e il relativom_id
(1
) vengono aggiunti allo stato e all'output.
Stato:
step | m_id | s1. Ts | s1. Evento | s2. Ts | s2. Evento | s3. Ts | s3. Evento |
---|---|---|---|---|---|---|---|
s1 | 1 | 00:08:00 | "Start" | X | X | X | X |
s2 | X | X | |||||
s3 | 0 | 00:01:00 | "Start" | 00:03:00 | "D" | 00:04:00 | "Stop" |
Nota
Sono ora presenti due sequenze attive nello stato .
Record 8
Ts | Event |
---|---|
11 min | "E" |
Registrare la valutazione in ogni passaggio:
s3
: il controllo 1 non viene passato perché lo stato dis2
è vuoto e il controllo 2 non viene passato perché non soddisfa las3
condizione diEvent == "Stop"
.s2
: il controllo 1 viene passato perché lo stato dis1
è nonempty e il record soddisfa la condizione diTs - s1.Ts < 5m
. Questa corrispondenza fa sì che lo stato dis1
venga cancellato e che la sequenza ins1
venga promossa as2
. Il record 8 e il relativom_id
(1
) vengono aggiunti allo stato e all'output.s1
: il controllo 1 è irrilevante perché non esiste alcun passaggio precedente e il controllo 2 non viene passato perché il record non soddisfa la condizione diEvent == "Start"
.
Stato:
step | m_id | s1. Ts | s1. Evento | s2. Ts | s2. Evento | s3. Ts | s3. Evento |
---|---|---|---|---|---|---|---|
s1 | X | X | X | X | |||
s2 | 1 | 00:08:00 | "Start" | 00:11:00 | "E" | X | X |
s3 | 0 | 00:01:00 | "Start" | 00:03:00 | "D" | 00:04:00 | "Stop" |
Record 9
Ts | Event |
---|---|
12m | "Stop" |
Registrare la valutazione in ogni passaggio:
s3
: il controllo 1 viene passato perchés2
non èempty e soddisfa las3
condizione diEvent == "Stop"
. Questa corrispondenza fa sì che lo stato dis2
venga cancellato e che la sequenza ins2
venga promossa as3
. Il record 9 e il relativom_id
(1
) vengono aggiunti allo stato e all'output.s2
: il controllo 1 non viene passato perché lo stato dis1
è vuoto e il controllo 2 non viene passato perchés2
manca una sequenza attiva.s1
: il controllo 1 non viene passato perché non è presente alcun passaggio precedente. passa il controllo 2 perché soddisfa la condizione diEvent == "Start"
. Questa corrispondenza avvia una nuova sequenza ins1
con un nuovom_id
oggetto .
Stato:
step | m_id | s1. Ts | s1. Evento | s2. Ts | s2. Evento | s3. Ts | s3. Evento |
---|---|---|---|---|---|---|---|
s1 | X | X | X | X | |||
s2 | X | X | |||||
s3 | 1 | 00:08:00 | "Start" | 00:11:00 | "E" | 00:12:00 | "Stop" |
Output finale
Ts | Event | m_id |
---|---|---|
00:01:00 | Inizio | 0 |
00:02:00 | G | 0 |
00:03:00 | D | 0 |
00:04:00 | Arresta | 0 |
00:08:00 | Inizio | 1 |
00:11:00 | E | 1 |
00:12:00 | Arresta | 1 |