Udostępnij przez


scan operator

Applies to: ✅Microsoft FabricAzure Data ExplorerAzure MonitorMicrosoft Sentinel

Skanuje dane, dopasowania i kompiluje sekwencje na podstawie predykatów.

Zgodne rekordy są określane zgodnie z predykatami zdefiniowanymi w krokach operatora. Predykat może zależeć od stanu wygenerowanego przez poprzednie kroki. Dane wyjściowe pasującego rekordu są określane przez rekord wejściowy i przypisania zdefiniowane w krokach operatora.

Syntax

T| scan [ with_match_id=MatchIdColumnName ] [ declare(ColumnDeclarations) ] with(StepDefinitions)

ColumnDeclarations syntax

ColumnName:ColumnType[=DefaultValue ] [, ... ]

StepDefinition syntax

step StepName [ output = all | last | none] :Condition [ =>Column=Assignment [, ... ] ] ;

Learn more about syntax conventions.

Parameters

Name Typ Required Description
T string ✔️ Źródło tabelaryczne danych wejściowych.
MatchIdColumnName string Nazwa kolumny typu long , która jest dołączana do danych wyjściowych w ramach wykonywania skanowania. Wskazuje 0-oparty na indeksie dopasowania rekordu.
ColumnDeclarations string Declares an extension to the schema of T. These columns are assigned values in the steps. If not assigned, the DefaultValue is returned. Unless otherwise specified, DefaultValue is null.
StepName string ✔️ Służy do odwołowania się do wartości w stanie skanowania pod kątem warunków i przypisań. Nazwa kroku musi być unikatowa.
Condition string ✔️ Wyrażenie, które oblicza wartość true lub false określa, które rekordy z danych wejściowych są zgodne z krokiem. Rekord pasuje do kroku, gdy warunek jest true ze stanem kroku lub stanem poprzedniego kroku.
Assignment string Wyrażenie skalarne przypisane do odpowiedniej kolumny, gdy rekord pasuje do kroku.
output string Steruje logiką wyjściową kroku w przypadku powtarzających się dopasowań. all Zwraca wszystkie rekordy pasujące do kroku, last generuje tylko ostatni rekord w serii powtarzających się dopasowań dla kroku i none nie generuje rekordów wyjściowych pasujących do kroku. Wartość domyślna to all.

Returns

Rekord dla każdego dopasowania rekordu z danych wejściowych do kroku. Schemat danych wyjściowych jest schematem źródła rozszerzonego z kolumną w klauzuli declare .

Scan logic

scan przechodzi przez serializowane dane wejściowe, rejestruj według rekordu, porównując każdy rekord z warunkiem każdego kroku, biorąc pod uwagę bieżący stan każdego kroku.

State

Podstawowy stan scan operatora można traktować jako tabelę z wierszem dla każdego stepelementu . Każdy krok zachowuje swój własny stan z najnowszymi wartościami kolumn i zadeklarowanymi zmiennymi ze wszystkich poprzednich kroków i bieżącego kroku. W razie potrzeby przechowuje również identyfikator dopasowania dla trwającej sekwencji.

If a scan operator has n steps named s_1, s_2, ..., s_n then step s_k would have k records in its state corresponding to s_1, s_2, ..., s_k. The StepName.ColumnName format is used to reference a value in the state. For instance, s_2.col1 would reference column col1 that belongs to step s_2 in the state of s_k. Szczegółowy przykład można znaleźć w przewodniku logiki skanowania.

Stan jest pusty i jest aktualizowany za każdym razem, gdy zeskanowany rekord wejściowy pasuje do kroku. When the state of the current step is nonempty, the step is referred to as having an active sequence.

Matching logic

Każdy rekord wejściowy jest oceniany względem wszystkich kroków w odwrotnej kolejności, od ostatniego kroku do pierwszego. When a record r is evaluated against some step s_k, the following logic is applied:

  • Check 1: If the state of the previous step (s_k-1) is nonempty, and r meets the Condition of s_k, then a match occurs. Dopasowanie prowadzi do następujących akcji:

    1. The state of s_k is cleared.
    2. The state of s_k-1 is promoted to become the state of s_k.
    3. The assignments of s_k are calculated and extend r.
    4. The extended r is added to the output and to the state of s_k.

    Note

    If Check 1 results in a match, Check 2 is disregarded, and r moves on to be evaluated against s_k-1.

  • Check 2: If the state of s_k has an active sequence or s_k is the first step, and r meets the Condition of s_k, then a match occurs. Dopasowanie prowadzi do następujących akcji:

    1. The assignments of s_k are calculated and extend r.
    2. The values that represent s_k in the state of s_k are replaced with the values of the extended r.
    3. If s_k is defined as output=all, the extended r is added to the output.
    4. If s_k is the first step, a new sequence begins and the match ID increases by 1. Ma to wpływ tylko na dane wyjściowe, gdy with_match_id jest używany.

Once the checks for s_k are complete, r moves on to be evaluated against s_k-1.

Szczegółowy przykład tej logiki można znaleźć w przewodniku logiki skanowania.

Examples

W przykładzie w tej sekcji pokazano, jak używać składni, aby ułatwić rozpoczęcie pracy.

The examples in this article use publicly available tables in the help cluster, such as the StormEvents table in the Samples database.

The examples in this article use publicly available tables, such as the Weather table in the Weather analytics sample gallery. Może być konieczne zmodyfikowanie nazwy tabeli w przykładowym zapytaniu, aby było zgodne z tabelą w obszarze roboczym.

Cumulative sum

Oblicz sumę skumulowaną dla kolumny wejściowej. The result of this example is equivalent to using 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

Suma zbiorcza dla wielu kolumn z warunkiem resetowania

Oblicz sumę skumulowaną dla dwóch kolumn wejściowych, zresetuj wartość sumy do bieżącej wartości rekordu, gdy suma skumulowana osiągnęła 10 lub więcej.

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

Wypełnianie kolumny do przodu

Wypełnij kolumnę ciągu do przodu. Każda pusta wartość jest przypisywana ostatnio widziana wartość brak.

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 A A
00:01:00 A
00:02:00 B B
00:03:00 B
00:04:00 B
00:06:00 C C
00:08:00 C
00:11:00 D D
00:12:00 D

Sessions tagging

Podziel dane wejściowe na sesje: sesja kończy się 30 minut po pierwszym zdarzeniu sesji, po którym rozpocznie się nowa sesja. Note the use of with_match_id flag, which assigns a unique value for each distinct match (session) of scan. Also note the special use of two steps in this example, inSession has true as condition so it captures and outputs all the records from the input while endSession captures records that happen more than 30m from the sessionStart value for the current match. Krok endSession ma output=none znaczenie, że nie generuje rekordów wyjściowych. Krok endSession służy do przechodzenia stanu bieżącego dopasowania z inSession do endSession, co umożliwia rozpoczęcie nowego dopasowania (sesji) rozpoczynającego się od bieżącego rekordu.

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 A 00:00:00 0
00:01:00 A 00:00:00 0
00:02:00 B 00:00:00 0
00:03:00 D 00:00:00 0
00:32:00 B 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

Obliczanie długości sesji na użytkownika

Oblicz czas rozpoczęcia sesji, godzinę zakończenia i czas trwania dla sesji każdego użytkownika przy użyciu scan operatora . Sesja jest definiowana jako okres między logowaniem użytkownika a kolejnym wylogowywaniem. partition Łącząc wartości i z elementami scan i output=noneoutput=all, ten wzorzec gwarantuje, że pojedynczy wiersz jest zwracany na sesję (tj. na parę logowania/wylogowywanie), a nie wiersz na zdarzenie.

Logika działa przez:

  • W kroku s1: przechwytywanie znacznika czasu logowania przy użyciu kroku skanowania z output=none
  • W kroku s2: Emitowanie wiersza tylko wtedy, gdy zostanie znalezione zgodne wylogowywanie przy użyciu polecenia output=all
let LogsEvents = datatable(Timestamp:datetime, userID:int, EventType:string)
[
    datetime(2024-05-28 08:15:23), 1, "login",
    datetime(2024-05-28 08:30:15), 2, "login",
    datetime(2024-05-28 09:10:27), 3, "login",
    datetime(2024-05-28 12:30:45), 1, "logout",
    datetime(2024-05-28 11:45:32), 2, "logout",
    datetime(2024-05-28 13:25:19), 3, "logout"
];
LogsEvents
| sort by userID, Timestamp
| partition hint.strategy=native by userID (
    sort by Timestamp asc 
    | scan declare (start: datetime, end: datetime, sessionDuration: timespan) with (
        step s1 output=none: EventType == "login" => start = Timestamp;
        step s2 output=all: EventType == "logout" => start = s1.start, end = Timestamp, sessionDuration = Timestamp - s1.start;
    )
)
| project start, end, userID, sessionDuration

Output

userID start end sessionDuration
1 2024-05-28 08:15:23.0000 2024-05-28 12:30:45.0000 04:15:22
3 2024-05-28 09:10:27.0000 2024-05-28 13:25:19.0000 04:14:52
2 2024-05-28 08:30:15.0000 2024-05-28 11:45:32.0000 03:15:17

Zdarzenia między uruchamianiem i zatrzymywaniem

Znajdź wszystkie sekwencje zdarzeń między zdarzeniem Start a zdarzeniem Stop , które występuje w ciągu 5 minut. Przypisz identyfikator dopasowania dla każdej sekwencji.

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 Start 0
00:02:00 B 0
00:03:00 D 0
00:04:00 Stop 0
00:08:00 Start 1
00:11:00 E 1
00:12:00 Stop 1

Obliczanie niestandardowego lejka zdarzeń

Oblicz ukończenie lejka sekwencji Hail —>Tornado>Thunderstorm Wind za pomocą State progów niestandardowych w czasie między zdarzeniami (Tornado w obrębie i 1h w obrębie ).Thunderstorm Wind2h This example is similar to the funnel_sequence_completion plugin, but allows greater flexibility.

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
Hail 50
Tornado 34
Thunderstorm Wind 32

Przewodnik po logice skanowania

This section demonstrates the scan logic using a step-by-step walkthrough of the Events between start and stop example:

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 Start 0
00:02:00 B 0
00:03:00 D 0
00:04:00 Stop 0
00:08:00 Start 1
00:11:00 E 1
00:12:00 Stop 1

The state

Pomyśl o stanie scan operatora jako tabeli z wierszem dla każdego kroku, w którym każdy krok ma swój własny stan. Ten stan zawiera najnowsze wartości kolumn i zadeklarowane zmienne ze wszystkich poprzednich kroków i bieżącego kroku. To learn more, see State.

W tym przykładzie stan można przedstawić przy użyciu następującej tabeli:

krok m_id s1.Ts s1.Event s2.Ts s2.Event s3.Ts s3.Event
s1 X X X X
s2 X X
s3

Znak "X" wskazuje, że określone pole nie ma znaczenia dla tego kroku.

Zgodna logika

This section follows the matching logic through each record of the Events table, explaining the transformation of the state and output at each step.

Note

Rekord wejściowy jest oceniany względem kroków w odwrotnej kolejności, od ostatniego kroku (s3) do pierwszego kroku (s1).

Record 1

Ts Event
0m "A"

Ocena rekordów w każdym kroku:

  • s3: Check 1 isn't passed because the state of s2 is empty, and Check 2 isn't passed because s3 lacks an active sequence.
  • s2: Check 1 isn't passed because the state of s1 is empty, and Check 2 isn't passed because s2 lacks an active sequence.
  • s1: Check 1 is irrelevant because there's no previous step. Check 2 isn't passed because the record doesn't meet the condition of Event == "Start". Record 1 is discarded without affecting the state or output.

State:

krok m_id s1.Ts s1.Event s2.Ts s2.Event s3.Ts s3.Event
s1 X X X X
s2 X X
s3

Record 2

Ts Event
1m "Start"

Ocena rekordów w każdym kroku:

  • s3: Check 1 isn't passed because the state of s2 is empty, and Check 2 isn't passed because s3 lacks an active sequence.
  • s2: Check 1 isn't passed because the state of s1 is empty, and Check 2 isn't passed because s2 lacks an active sequence.
  • s1: Check 1 is irrelevant because there's no previous step. Check 2 is passed because the record meets the condition of Event == "Start". To dopasowanie inicjuje nową sekwencję i jest przypisywana m_id . Record 2 and its m_id (0) are added to the state and the output.

State:

krok m_id s1.Ts s1.Event s2.Ts s2.Event s3.Ts s3.Event
s1 0 00:01:00 "Start" X X X X
s2 X X
s3

Record 3

Ts Event
2m "B"

Ocena rekordów w każdym kroku:

  • s3: Check 1 isn't passed because the state of s2 is empty, and Check 2 isn't passed because s3 lacks an active sequence.
  • s2: Check 1 is passed because the state of s1 is nonempty and the record meets the condition of Ts - s1.Ts < 5m. To dopasowanie powoduje wyczyszczenie stanu s1 i sekwencję w s1 celu podwyższenia poziomu do s2. Record 3 and its m_id (0) are added to the state and the output.
  • s1: Check 1 is irrelevant because there's no previous step, and Check 2 isn't passed because the record doesn't meet the condition of Event == "Start".

State:

krok m_id s1.Ts s1.Event s2.Ts s2.Event s3.Ts s3.Event
s1 X X X X
s2 0 00:01:00 "Start" 00:02:00 "B" X X
s3

Record 4

Ts Event
3m "D"

Ocena rekordów w każdym kroku:

  • s3: Check 1 isn't passed because the record doesn't meet the condition of Event == "Stop", and Check 2 isn't passed because s3 lacks an active sequence.
  • s2: Check 1 isn't passed because the state of s1 is empty. it passes Check 2 because it meets the condition of Ts - s1.Ts < 5m. Record 4 and its m_id (0) are added to the state and the output. Wartości z tego rekordu zastępują poprzednie wartości stanu dla s2.Ts i s2.Event.
  • s1: Check 1 is irrelevant because there's no previous step, and Check 2 isn't passed because the record doesn't meet the condition of Event == "Start".

State:

krok m_id s1.Ts s1.Event s2.Ts s2.Event s3.Ts s3.Event
s1 X X X X
s2 0 00:01:00 "Start" 00:03:00 "D" X X
s3

Record 5

Ts Event
4m "Stop"

Ocena rekordów w każdym kroku:

  • s3: Check 1 is passed because s2 is nonempty and it meets the s3 condition of Event == "Stop". To dopasowanie powoduje wyczyszczenie stanu s2 i sekwencję w s2 celu podwyższenia poziomu do s3. Record 5 and its m_id (0) are added to the state and the output.
  • s2: Check 1 isn't passed because the state of s1 is empty, and Check 2 isn't passed because s2 lacks an active sequence.
  • s1: Check 1 is irrelevant because there's no previous step. Check 2 isn't passed because the record doesn't meet the condition of Event == "Start".

State:

krok m_id s1.Ts s1.Event s2.Ts s2.Event s3.Ts s3.Event
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
6m "C"

Ocena rekordów w każdym kroku:

  • s3: Check 1 isn't passed because the state of s2 is empty, and Check 2 isn't passed because s3 doesn't meet the s3 condition of Event == "Stop".
  • s2: Check 1 isn't passed because the state of s1 is empty, and Check 2 isn't passed because s2 lacks an active sequence.
  • s1: Check 1 isn't passed because there's no previous step, and Check 2 isn't passed because it doesn't meet the condition of Event == "Start". Record 6 is discarded without affecting the state or output.

State:

krok m_id s1.Ts s1.Event s2.Ts s2.Event s3.Ts s3.Event
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"

Ocena rekordów w każdym kroku:

  • s3: Check 1 isn't passed because the state of s2 is empty, and Check 2 isn't passed because it doesn't meet the condition of Event == "Stop".
  • s2: Check 1 isn't passed because the state of s1 is empty, and Check 2 isn't passed because s2 lacks an active sequence.
  • s1: Check 1 isn't passed because there's no previous step. it passes Check 2 because it meets the condition of Event == "Start". To dopasowanie inicjuje nową sekwencję przy s1 użyciu nowego m_idelementu . Record 7 and its m_id (1) are added to the state and the output.

State:

krok m_id s1.Ts s1.Event s2.Ts s2.Event s3.Ts s3.Event
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"

Note

Teraz istnieją dwie aktywne sekwencje w stanie .

Record 8

Ts Event
11m "E"

Ocena rekordów w każdym kroku:

  • s3: Check 1 isn't passed because the state of s2 is empty, and Check 2 isn't passed because it doesn't meet the s3 condition of Event == "Stop".
  • s2: Check 1 is passed because the state of s1 is nonempty and the record meets the condition of Ts - s1.Ts < 5m. To dopasowanie powoduje wyczyszczenie stanu s1 i sekwencję w s1 celu podwyższenia poziomu do s2. Record 8 and its m_id (1) are added to the state and the output.
  • s1: Check 1 is irrelevant because there's no previous step, and Check 2 isn't passed because the record doesn't meet the condition of Event == "Start".

State:

krok m_id s1.Ts s1.Event s2.Ts s2.Event s3.Ts s3.Event
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"

Ocena rekordów w każdym kroku:

  • s3: Check 1 is passed because s2 is nonempty and it meets the s3 condition of Event == "Stop". To dopasowanie powoduje wyczyszczenie stanu s2 i sekwencję w s2 celu podwyższenia poziomu do s3. Record 9 and its m_id (1) are added to the state and the output.
  • s2: Check 1 isn't passed because the state of s1 is empty, and Check 2 isn't passed because s2 lacks an active sequence.
  • s1: Check 1 isn't passed because there's no previous step. it passes Check 2 because it meets the condition of Event == "Start". To dopasowanie inicjuje nową sekwencję przy s1 użyciu nowego m_idelementu .

State:

krok m_id s1.Ts s1.Event s2.Ts s2.Event s3.Ts s3.Event
s1 X X X X
s2 X X
s3 1 00:08:00 "Start" 00:11:00 "E" 00:12:00 "Stop"

Final output

Ts Event m_id
00:01:00 Start 0
00:02:00 B 0
00:03:00 D 0
00:04:00 Stop 0
00:08:00 Start 1
00:11:00 E 1
00:12:00 Stop 1