Opérateur scan
S’applique à : ✅Microsoft Fabric✅Azure Data Explorer✅Azure Monitor✅Microsoft Sentinel
Analyse les données, établit une correspondance et génère des séquences en fonction des prédicats.
Les enregistrements correspondants sont déterminés en fonction des prédicats définis dans les étapes de l’opérateur. Un prédicat peut dépendre de l’état généré par les étapes précédentes. La sortie de l’enregistrement correspondant est déterminée par l’enregistrement d’entrée et les affectations définis dans les étapes de l’opérateur.
T | scan
[ with_match_id
=
MatchIdColumnName ] [ declare
(
ColumnDeclarations )
] with
(
StepDefinitions )
ColumnName :
ColumnType[=
DefaultValue ] [,
... ]
step
StepName [ output
| all
last
= | none
] :
Condition [ =>
Affectation de colonne =
[,
... ] ];
En savoir plus sur les conventions de syntaxe.
Nom | Type | Requise | Description |
---|---|---|---|
T | string |
✔️ | Source tabulaire d’entrée. |
MatchIdColumnName | string |
Nom d’une colonne de type long ajoutée à la sortie dans le cadre de l’exécution de l’analyse. Indique l’index de base 0 de la correspondance pour l’enregistrement. |
|
ColumnDeclarations | string |
Déclare une extension au schéma de T. Ces colonnes sont affectées à des valeurs dans les étapes. S’il n’est pas affecté, DefaultValue est retourné. Sauf indication contraire, DefaultValue est null . |
|
StepName | string |
✔️ | Utilisé pour référencer des valeurs dans l’état de l’analyse pour les conditions et les affectations. Le nom de l’étape doit être unique. |
Condition | string |
✔️ | Expression qui prend true la valeur ou false définit les enregistrements de l’entrée correspondant à l’étape. Un enregistrement correspond à l’étape lorsque la condition est true avec l’état de l’étape ou avec l’état de l’étape précédente. |
Affectation | string |
Expression scalaire affectée à la colonne correspondante lorsqu’un enregistrement correspond à une étape. | |
output |
string |
Contrôle la logique de sortie de l’étape sur les correspondances répétées. all génère tous les enregistrements correspondant à l’étape, last génère uniquement le dernier enregistrement d’une série de correspondances répétées pour l’étape et none ne génère pas d’enregistrements correspondant à l’étape. Par défaut, il s’agit de all . |
Enregistrement pour chaque correspondance d’un enregistrement de l’entrée à une étape. Le schéma de la sortie est le schéma de la source étendue avec la colonne de la declare
clause.
scan
passe au-dessus des données d’entrée sérialisées, enregistrement par enregistrement, comparant chaque enregistrement à la condition de chaque étape tout en tenant compte de l’état actuel de chaque étape.
L’état sous-jacent de l’opérateur scan
peut être considéré comme une table avec une ligne pour chaque step
. Chaque étape conserve son propre état avec les valeurs les plus récentes des colonnes et les variables déclarées de toutes les étapes précédentes et de l’étape actuelle. Le cas échéant, il contient également l’ID de correspondance pour la séquence en cours.
Si un opérateur d’analyse a n étapes nommées s_1, s_2, ..., s_n l’étape s_k aurait des enregistrements k dans son état correspondant à s_1, s_2, ..., s_k. StepName.Le format ColumnName est utilisé pour référencer une valeur dans l’état. Par exemple, s_2.col1
référence la colonne col1
qui appartient à l’étape s_2 dans l’état de s_k. Pour obtenir un exemple détaillé, consultez la procédure pas à pas de la logique d’analyse.
L’état démarre vide et met à jour chaque fois qu’un enregistrement d’entrée analysé correspond à une étape. Lorsque l’état de l’étape actuelle n’est pasmpty, l’étape est appelée avoir une séquence active.
Chaque enregistrement d’entrée est évalué par rapport à toutes les étapes dans l’ordre inverse, de la dernière étape au premier. Lorsqu’un enregistrement r est évalué par rapport à une étape s_k, la logique suivante est appliquée :
Vérifiez 1 : Si l’état de l’étape précédente (s_k-1) n’est pasmpty, et r répond à la condition de s_k, une correspondance se produit. La correspondance mène aux actions suivantes :
- L’état de s_k est effacé.
- L’état de s_k-1 est promu pour devenir l’état de s_k.
- Les affectations de s_k sont calculées et étendent r.
- Le r étendu est ajouté à la sortie et à l’état de s_k.
Notes
Si la vérification 1 entraîne une correspondance, la vérification 2 est ignorée et r passe à l’évaluation par rapport à s_k-1.
Vérifier 2 : Si l’état de s_k a une séquence active ou s_k est la première étape, et r répond à la condition de s_k, une correspondance se produit. La correspondance mène aux actions suivantes :
- Les affectations de s_k sont calculées et étendent r.
- Les valeurs qui représentent s_k dans l’état de s_k sont remplacées par les valeurs du r étendu.
- Si s_k est défini comme
output=all
, le r étendu est ajouté à la sortie. - Si s_k est la première étape, une nouvelle séquence commence et l’ID de correspondance augmente de
1
. Cela affecte uniquement la sortie quandwith_match_id
elle est utilisée.
Une fois que les vérifications de s_k sont terminées, r passe à l’évaluation par rapport à s_k-1.
Pour obtenir un exemple détaillé de cette logique, consultez la procédure pas à pas de la logique d’analyse.
Calculez la somme cumulative d’une colonne d’entrée. Le résultat de cet exemple équivaut à utiliser 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;
)
Sortie
x | cumulative_x |
---|---|
1 | 1 |
2 | 3 |
3 | 6 |
4 | 10 |
5 | 15 |
Calculez la somme cumulative pour deux colonnes d’entrée, réinitialisez la valeur de somme sur la valeur d’enregistrement actuelle chaque fois que la somme cumulative a atteint 10 ou plus.
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);
)
Sortie
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 |
Remplissez une colonne de chaîne. Chaque valeur vide est affectée à la dernière valeur aucunempty vue.
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);
)
Sortie
Ts | Événement | Event_filled |
---|---|---|
00:00:00 | A | A |
00:01:00 | A | |
00:02:00 | G | G |
00:03:00 | G | |
00:04:00 | G | |
00:06:00 | C | C |
00:08:00 | C | |
00:11:00 | D | D |
00:12:00 | D |
Divisez l’entrée en sessions : une session se termine 30 minutes après le premier événement de la session, après lequel une nouvelle session démarre. Notez l’utilisation de with_match_id
l’indicateur, qui affecte une valeur unique pour chaque correspondance distincte (session) de l’analyse. Notez également l’utilisation spéciale de deux étapes dans cet exemple, inSession
a true
comme condition qu’elle capture et génère tous les enregistrements de l’entrée, tandis que endSession
les enregistrements capturent des enregistrements qui se produisent plus de 30m à partir de la valeur de la sessionStart
correspondance actuelle. L’étape endSession
a output=none
pour signification qu’elle ne produit pas d’enregistrements de sortie. L’étape endSession
permet d’avancer l’état de la correspondance actuelle à endSession
partir de inSession
, ce qui permet à une nouvelle correspondance (session) de commencer, en commençant à partir de l’enregistrement actif.
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;
)
Sortie
Ts | Événement | sessionStart | session_id |
---|---|---|---|
00:00:00 | A | 00:00:00 | 0 |
00:01:00 | A | 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 | C | 00:32:00 | 1 |
00:38:00 | D | 00:32:00 | 1 |
00:41:00 | E | 00:32:00 | 1 |
01:15:00 | A | 01:15:00 | 2 |
Recherchez toutes les séquences d’événements entre l’événement Start
et l’événement Stop
qui se produisent dans les 5 minutes. Attribuez un ID de correspondance pour chaque séquence.
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;
)
Sortie
Ts | Événement | m_id |
---|---|---|
00:01:00 | Démarrer | 0 |
00:02:00 | G | 0 |
00:03:00 | D | 0 |
00:04:00 | Stop | 0 |
00:08:00 | Démarrer | 1 |
00:11:00 | E | 1 |
00:12:00 | Stop | 1 |
Calculez l’achèvement d’un entonnoir de la séquence Hail
:Thunderstorm Wind
Tornado
>> avec State
des seuils personnalisés sur les heures entre les événements (Tornado
au sein 1h
et Thunderstorm Wind
dans ).2h
Cet exemple est similaire au plug-in funnel_sequence_completion, mais permet une plus grande flexibilité.
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
Sortie
Type d’événement | dcount_State |
---|---|
Grêle | 50 |
Tornade | 34 |
Vent d’orage | 32 |
Cette section illustre la logique d’analyse à l’aide d’une procédure pas à pas des événements entre l’exemple de démarrage et d’arrêt :
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;
)
Considérez l’état de l’opérateur scan
comme une table avec une ligne pour chaque étape, dans laquelle chaque étape a son propre état. Cet état contient les valeurs les plus récentes des colonnes et des variables déclarées de toutes les étapes précédentes et de l’étape actuelle. Pour en savoir plus, consultez État.
Pour cet exemple, l’état peut être représenté avec le tableau suivant :
step | m_id | s1. Ts | s1. Événement | s2. Ts | s2. Événement | s3. Ts | s3. Événement |
---|---|---|---|---|---|---|---|
s1 | X | X | X | X | |||
s2 | X | X | |||||
s3 |
Le « X » indique qu’un champ spécifique n’est pas pertinent pour cette étape.
Cette section suit la logique correspondante à travers chaque enregistrement de la Events
table, expliquant la transformation de l’état et de la sortie à chaque étape.
Notes
Un enregistrement d’entrée est évalué par rapport aux étapes dans l’ordre inverse, de la dernière étape (s3
) à la première étape (s1
).
Ts | Événement |
---|---|
0m | "A" |
Enregistrez l’évaluation à chaque étape :
s3
: La vérification 1 n’est pas passée, car l’état des2
l’état est vide, et la vérification 2 n’est pas passée, cars3
il manque une séquence active.s2
: La vérification 1 n’est pas passée, car l’état des1
l’état est vide, et la vérification 2 n’est pas passée, cars2
il manque une séquence active.s1
: Vérifier 1 n’est pas pertinent, car il n’y a pas d’étape précédente. La vérification 2 n’est pas passée, car l’enregistrement ne répond pas à la condition deEvent == "Start"
. L’enregistrement 1 est ignoré sans affecter l’état ou la sortie.
État :
step | m_id | s1. Ts | s1. Événement | s2. Ts | s2. Événement | s3. Ts | s3. Événement |
---|---|---|---|---|---|---|---|
s1 | X | X | X | X | |||
s2 | X | X | |||||
s3 |
Ts | Événement |
---|---|
1 min | « Démarrer » |
Enregistrez l’évaluation à chaque étape :
s3
: La vérification 1 n’est pas passée, car l’état des2
l’état est vide, et la vérification 2 n’est pas passée, cars3
il manque une séquence active.s2
: La vérification 1 n’est pas passée, car l’état des1
l’état est vide, et la vérification 2 n’est pas passée, cars2
il manque une séquence active.s1
: Vérifier 1 n’est pas pertinent, car il n’y a pas d’étape précédente. La vérification 2 est passée, car l’enregistrement répond à la condition deEvent == "Start"
. Cette correspondance lance une nouvelle séquence, et ellem_id
est affectée. L’enregistrement 2 et sonm_id
(0
) sont ajoutés à l’état et à la sortie.
État :
step | m_id | s1. Ts | s1. Événement | s2. Ts | s2. Événement | s3. Ts | s3. Événement |
---|---|---|---|---|---|---|---|
s1 | 0 | 00:01:00 | « Démarrer » | X | X | X | X |
s2 | X | X | |||||
s3 |
Ts | Événement |
---|---|
2 min | « B » |
Enregistrez l’évaluation à chaque étape :
s3
: La vérification 1 n’est pas passée, car l’état des2
l’état est vide, et la vérification 2 n’est pas passée, cars3
il manque une séquence active.s2
: La vérification 1 est passée, car l’état des1
l’état n’est pasmpty et que l’enregistrement répond à la condition deTs - s1.Ts < 5m
. Cette correspondance entraîne l’effacement des1
l’état et la séquence danss1
laquelle être promues2
. L’enregistrement 3 et sonm_id
(0
) sont ajoutés à l’état et à la sortie.s1
: La vérification 1 n’est pas pertinente, car il n’y a pas d’étape précédente et la vérification 2 n’est pas passée, car l’enregistrement ne répond pas à la condition deEvent == "Start"
.
État :
step | m_id | s1. Ts | s1. Événement | s2. Ts | s2. Événement | s3. Ts | s3. Événement |
---|---|---|---|---|---|---|---|
s1 | X | X | X | X | |||
s2 | 0 | 00:01:00 | « Démarrer » | 00:02:00 | « B » | X | X |
s3 |
Ts | Événement |
---|---|
3 min | « D » |
Enregistrez l’évaluation à chaque étape :
s3
: La vérification 1 n’est pas passée, car l’enregistrement ne répond pas à la condition deEvent == "Stop"
, et la vérification 2 n’est pas passée, cars3
il manque une séquence active.s2
: La vérification 1 n’est pas passée, car l’état ests1
vide. il passe Check 2 car il répond à la condition deTs - s1.Ts < 5m
. L’enregistrement 4 et sonm_id
(0
) sont ajoutés à l’état et à la sortie. Les valeurs de cet enregistrement remplacent les valeurs d’état précédentes pours2.Ts
ets2.Event
.s1
: La vérification 1 n’est pas pertinente, car il n’y a pas d’étape précédente et la vérification 2 n’est pas passée, car l’enregistrement ne répond pas à la condition deEvent == "Start"
.
État :
step | m_id | s1. Ts | s1. Événement | s2. Ts | s2. Événement | s3. Ts | s3. Événement |
---|---|---|---|---|---|---|---|
s1 | X | X | X | X | |||
s2 | 0 | 00:01:00 | « Démarrer » | 00:03:00 | « D » | X | X |
s3 |
Ts | Événement |
---|---|
4 min | « Arrêter » |
Enregistrez l’évaluation à chaque étape :
s3
: La vérification 1 est passée, cars2
elle n’est pas vide et répond à las3
condition deEvent == "Stop"
. Cette correspondance entraîne l’effacement des2
l’état et la séquence danss2
laquelle être promues3
. L’enregistrement 5 et sonm_id
(0
) sont ajoutés à l’état et à la sortie.s2
: La vérification 1 n’est pas passée, car l’état des1
l’état est vide, et la vérification 2 n’est pas passée, cars2
il manque une séquence active.s1
: Vérifier 1 n’est pas pertinent, car il n’y a pas d’étape précédente. La vérification 2 n’est pas passée, car l’enregistrement ne répond pas à la condition deEvent == "Start"
.
État :
step | m_id | s1. Ts | s1. Événement | s2. Ts | s2. Événement | s3. Ts | s3. Événement |
---|---|---|---|---|---|---|---|
s1 | X | X | X | X | |||
s2 | X | X | |||||
s3 | 0 | 00:01:00 | « Démarrer » | 00:03:00 | « D » | 00:04:00 | « Arrêter » |
Ts | Événement |
---|---|
6m | « C » |
Enregistrez l’évaluation à chaque étape :
s3
: La vérification 1 n’est pas passée, car l’état des2
l’état est vide, et la vérification 2 n’est pas passée, cars3
elle ne répond pas à las3
condition deEvent == "Stop"
.s2
: La vérification 1 n’est pas passée, car l’état des1
l’état est vide, et la vérification 2 n’est pas passée, cars2
il manque une séquence active.s1
: La vérification 1 n’est pas passée, car il n’y a pas d’étape précédente, et La vérification 2 n’est pas passée, car elle ne répond pas à la condition deEvent == "Start"
. L’enregistrement 6 est ignoré sans affecter l’état ou la sortie.
État :
step | m_id | s1. Ts | s1. Événement | s2. Ts | s2. Événement | s3. Ts | s3. Événement |
---|---|---|---|---|---|---|---|
s1 | X | X | X | X | |||
s2 | X | X | |||||
s3 | 0 | 00:01:00 | « Démarrer » | 00:03:00 | « D » | 00:04:00 | « Arrêter » |
Ts | Événement |
---|---|
8m | « Démarrer » |
Enregistrez l’évaluation à chaque étape :
s3
: La vérification 1 n’est pas passée, car l’état ests2
vide et la vérification 2 n’est pas passée, car elle ne répond pas à la condition deEvent == "Stop"
.s2
: La vérification 1 n’est pas passée, car l’état des1
l’état est vide, et la vérification 2 n’est pas passée, cars2
il manque une séquence active.s1
: La vérification 1 n’est pas passée, car il n’y a pas d’étape précédente. il passe Check 2 car il répond à la condition deEvent == "Start"
. Cette correspondance lance une nouvelle séquence avecs1
un nouveaum_id
. L’enregistrement 7 et sonm_id
(1
) sont ajoutés à l’état et à la sortie.
État :
step | m_id | s1. Ts | s1. Événement | s2. Ts | s2. Événement | s3. Ts | s3. Événement |
---|---|---|---|---|---|---|---|
s1 | 1 | 00:08:00 | « Démarrer » | X | X | X | X |
s2 | X | X | |||||
s3 | 0 | 00:01:00 | « Démarrer » | 00:03:00 | « D » | 00:04:00 | « Arrêter » |
Notes
Il existe maintenant deux séquences actives dans l’état.
Ts | Événement |
---|---|
11 min | « E » |
Enregistrez l’évaluation à chaque étape :
s3
: La vérification 1 n’est pas passée, car l’état ests2
vide et la vérification 2 n’est pas passée, car elle ne répond pas à las3
condition deEvent == "Stop"
.s2
: La vérification 1 est passée, car l’état des1
l’état n’est pasmpty et que l’enregistrement répond à la condition deTs - s1.Ts < 5m
. Cette correspondance entraîne l’effacement des1
l’état et la séquence danss1
laquelle être promues2
. L’enregistrement 8 et sonm_id
(1
) sont ajoutés à l’état et à la sortie.s1
: La vérification 1 n’est pas pertinente, car il n’y a pas d’étape précédente et la vérification 2 n’est pas passée, car l’enregistrement ne répond pas à la condition deEvent == "Start"
.
État :
step | m_id | s1. Ts | s1. Événement | s2. Ts | s2. Événement | s3. Ts | s3. Événement |
---|---|---|---|---|---|---|---|
s1 | X | X | X | X | |||
s2 | 1 | 00:08:00 | « Démarrer » | 00:11:00 | « E » | X | X |
s3 | 0 | 00:01:00 | « Démarrer » | 00:03:00 | « D » | 00:04:00 | « Arrêter » |
Ts | Événement |
---|---|
12 m | « Arrêter » |
Enregistrez l’évaluation à chaque étape :
s3
: La vérification 1 est passée, cars2
elle n’est pas vide et répond à las3
condition deEvent == "Stop"
. Cette correspondance entraîne l’effacement des2
l’état et la séquence danss2
laquelle être promues3
. L’enregistrement 9 et sonm_id
(1
) sont ajoutés à l’état et à la sortie.s2
: La vérification 1 n’est pas passée, car l’état des1
l’état est vide, et la vérification 2 n’est pas passée, cars2
il manque une séquence active.s1
: La vérification 1 n’est pas passée, car il n’y a pas d’étape précédente. il passe Check 2 car il répond à la condition deEvent == "Start"
. Cette correspondance lance une nouvelle séquence avecs1
un nouveaum_id
.
État :
step | m_id | s1. Ts | s1. Événement | s2. Ts | s2. Événement | s3. Ts | s3. Événement |
---|---|---|---|---|---|---|---|
s1 | X | X | X | X | |||
s2 | X | X | |||||
s3 | 1 | 00:08:00 | « Démarrer » | 00:11:00 | « E » | 00:12:00 | « Arrêter » |
Ts | Événement | m_id |
---|---|---|
00:01:00 | Démarrer | 0 |
00:02:00 | G | 0 |
00:03:00 | D | 0 |
00:04:00 | Stop | 0 |
00:08:00 | Démarrer | 1 |
00:11:00 | E | 1 |
00:12:00 | Stop | 1 |