共用方式為


掃描運算子

適用於:✅Microsoft網狀架構Azure 數據✅總管 Azure 監視器✅Microsoft Sentinel

根據述詞掃描數據、比對和建置序列。

比對記錄是根據運算符步驟中定義的述詞來決定。 述詞可以取決於先前步驟所產生的狀態。 比對記錄的輸出取決於運算符步驟中定義的輸入記錄和指派。

語法

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

ColumnDeclarations 語法

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

StepDefinition 語法

stepStepName [ output | = nonealllast | ] : Condition [ Column = Assignment [, => ... ] ];

深入瞭解 語法慣例

參數

姓名 類型​​ 必要 描述
T string ✔️ 輸入表格式來源。
MatchIdColumnName string 在掃描執行時附加至輸出之類型的數據 long 行名稱。 指出記錄相符專案的 0 型索引。
ColumnDeclarations string 宣告 T 架構的延伸模組。這些步驟中會指派這些數據行的值。 如果未指派,則會 傳回DefaultValue 。 除非另有指定, 否則 DefaultValuenull
StepName string ✔️ 用來參考掃描條件和指派狀態中的值。 步驟名稱必須是唯一的。
Condition string ✔️ 評估為 truefalse 的表示式,定義輸入中的哪些記錄符合步驟。 當條件為 true 步驟狀態或上一個步驟的狀態時,記錄會比對步驟。
指派 string 當記錄符合步驟時,指派給對應數據行的純量表達式。
output string 在重複的相符專案上控制步驟的輸出邏輯。 all 輸出符合步驟的所有記錄、 last 只輸出步驟一系列重複比對中的最後一筆記錄,而且 none 不會輸出符合步驟的記錄。 預設值為 all

傳回

從輸入到步驟之記錄的每個相符項目記錄。 輸出的架構是以 子句中的數據 declare 行擴充的來源架構。

掃描邏輯

scan 會逐筆記錄逐一串行化輸入數據,比較每個記錄與每個步驟的條件,同時考慮到每個步驟的目前狀態。

州/省

運算子的基礎狀態 scan 可以視為具有每個 step數據列的數據表。 每個步驟都會使用數據行的最新值,以及先前所有步驟和目前步驟中宣告的變數,維護自己的狀態。 如果相關,它也會保留進行中序列的相符標識符。

如果掃描運算符具有名為 s_1、s_2...、...、s_n的 n 個步驟,則步驟s_k會在其狀態中具有與s_1s_2、...、s_k對應的 k 記錄。 StepNameColumnName 格式是用來參考狀態中的值。 例如,s_2.col1會參考col1屬於s_k狀態之步驟s_2的數據行。 如需詳細範例,請參閱 掃描邏輯逐步解說

每當掃描的輸入記錄符合步驟時,狀態就會啟動空白並更新。 當目前步驟的狀態為非空白時,步驟稱為具有 作用中序列

比對邏輯

每個輸入記錄都會根據從最後一個步驟到第一個步驟的所有反向順序進行評估。 當記錄 r 針對某些步驟 s_k進行評估時,會套用下列邏輯:

  • 檢查 1:如果上一個步驟 (s_k-1) 的狀態是空的,且 r 符合 s_k 的條件,則會發生相符專案。 比對會導致下列動作:

    1. 清除s_k的狀態
    2. s_k-1 的狀態會升級為成為s_k的狀態
    3. 計算s_k指派並擴充 r
    4. 擴充 r 會新增至輸出和s_k的狀態

    注意

    如果 Check 1 會產生相符專案,則會忽略 Check 2,r 會繼續針對 s_k-1 進行評估。

  • 檢查 2:如果s_k的狀態為使用中序列或s_k是第一個步驟,而 r 符合 s_k 的條件,則會發生比對。 比對會導致下列動作:

    1. 計算s_k指派並擴充 r
    2. 表示s_k狀態s_k的值會取代為擴充 r 的值。
    3. 如果 s_k 定義為 output=all,則會將擴充 r 新增至輸出。
    4. 如果 s_k 是第一個步驟,就會開始新的序列,而比對標識符會依 1增加。 這隻會影響使用 時的 with_match_id 輸出。

檢查s_k完成後,r繼續評估 s_k-1

如需此邏輯的詳細範例,請參閱 掃描邏輯逐步解說

範例

累計總和

計算輸入數據行的累計總和。 此範例的結果相當於使用 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;
)

輸出

x cumulative_x
1 7
2 3
3 6
4 10
5 15

具有重設條件之多個數據行的累計總和

計算兩個輸入數據行的累計總和,每當累計總和達到10個以上時,將總和重設為當前記錄值。

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);
)

輸出

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

向前填入數據行

向前填入字串數據行。 每個空白值都會指派最後一個未見空值。

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);
)

輸出

Ts 活動 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

會話標記

將輸入分割成會話:會話會在會話的第一個事件之後 30 分鐘結束,之後就會啟動新的會話。 請注意旗標的使用with_match_id,這會為掃描的每個相異相符專案(會話)指派唯一值。 另請注意,在此範例中特別使用兩個步驟,具有 true 條件,inSession因此它會從輸入擷取和輸出所有記錄,同時endSession擷取目前相符專案值超過 30m sessionStart 的記錄。 步驟 endSession 表示 output=none 它不會產生輸出記錄。 步驟 endSession 是用來將目前相符專案的狀態從 inSession 前進到 endSession,讓新的比對 (session) 從目前的記錄開始。

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;
)

輸出

Ts 活動 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

開始和停止之間的事件

尋找事件 Start 與 5 分鐘內發生之事件之間的所有事件 Stop 序列。 為每個序列指派相符標識碼。

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;
)

輸出

Ts 活動 m_id
00:01:00 啟動 0
00:02:00 B 0
00:03:00 D 0
00:04:00 停止 0
00:08:00 啟動 1
00:11:00 E 1
00:12:00 停止 1

計算事件的自定義漏鬥圖

計算序列Hail的漏鬥完成 -Tornado>Thunderstorm Wind> 依據State事件之間的時間自定義臨界值(Tornado1h 內和Thunderstorm Wind內)。2h 此範例與 funnel_sequence_completion外掛程式類似,但允許更大的彈性。

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

輸出

EventType dcount_State
冰雹 50
龍捲風 34
雷暴風 32

掃描邏輯逐步解說

本節示範使用啟動與停止之間事件範例的逐步解說來示範掃描邏輯

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;
)

狀態

請將 運算符的狀態視為具有每個步驟數據列的 scan 數據表,其中每個步驟都有自己的狀態。 此狀態包含所有先前步驟和目前步驟中數據行和宣告變數的最新值。 若要深入瞭解,請參閱 狀態

在此範例中,狀態可以使用下表來表示:

step m_id s1.Ts s1.事件 s2.Ts s2.事件 s3.Ts s3.事件
s1 X X X X
s2 X X
S3

“X” 表示特定欄位與此步驟無關。

比對邏輯

本節會透過數據表的每個記錄遵循比對Events邏輯,說明每個步驟的狀態和輸出轉換。

注意

輸入記錄會根據從最後一個步驟() 到第一個步驟的s3反向順序來評估步驟。s1

記錄 1

Ts 活動
0m "A"

記錄每個步驟的評估:

  • s3檢查 1 不會通過,因為 的狀態 s2 是空的,而且 檢查 2 未通過,因為 s3 缺少作用中的序列。
  • s2檢查 1 不會通過,因為 的狀態 s1 是空的,而且 檢查 2 未通過,因為 s2 缺少作用中的序列。
  • s1檢查 1 無關緊要,因為沒有上一個步驟。 檢查 2 未通過,因為記錄不符合 的條件 Event == "Start"記錄 1 會捨棄,而不會影響狀態或輸出。

step m_id s1.Ts s1.事件 s2.Ts s2.事件 s3.Ts s3.事件
s1 X X X X
s2 X X
S3

記錄 2

Ts 活動
1 分鐘 “Start”

記錄每個步驟的評估:

  • s3檢查 1 不會通過,因為 的狀態 s2 是空的,而且 檢查 2 未通過,因為 s3 缺少作用中的序列。
  • s2檢查 1 不會通過,因為 的狀態 s1 是空的,而且 檢查 2 未通過,因為 s2 缺少作用中的序列。
  • s1檢查 1 無關緊要,因為沒有上一個步驟。 檢查 2 已通過,因為記錄符合 的條件 Event == "Start"。 此比對會起始新的序列,並 m_id 指派 。 記錄 2 及其 m_id0) 會新增至狀態和輸出。

step m_id s1.Ts s1.事件 s2.Ts s2.事件 s3.Ts s3.事件
s1 0 00:01:00 “Start” X X X X
s2 X X
S3

記錄 3

Ts 活動
2 分 "B"

記錄每個步驟的評估:

  • s3檢查 1 不會通過,因為 的狀態 s2 是空的,而且 檢查 2 未通過,因為 s3 缺少作用中的序列。
  • s2檢查 1 是傳遞的,因為 的狀態 s1 是空的,且記錄符合 的條件 Ts - s1.Ts < 5m。 此比對會導致 清除的狀態 s1 ,並將中的 s1 序列升階為 s2記錄 3 及其 m_id0) 會新增至狀態和輸出。
  • s1檢查 1 無關緊要,因為沒有上一個步驟,而且 檢查 2 未通過,因為記錄不符合 的條件 Event == "Start"

step m_id s1.Ts s1.事件 s2.Ts s2.事件 s3.Ts s3.事件
s1 X X X X
s2 0 00:01:00 “Start” 00:02:00 "B" X X
S3

記錄 4

Ts 活動
3 個月 "D"

記錄每個步驟的評估:

  • s3檢查 1 未通過,因為記錄不符合 的條件 Event == "Stop",而且 檢查 2 未通過,因為 s3 缺少使用中序列。
  • s2檢查 1 未通過,因為 的狀態 s1 是空的。 它會通過 Check 2 ,因為它符合 的條件 Ts - s1.Ts < 5m記錄 4 及其 m_id0) 會新增至狀態和輸出。 此記錄中的值會覆寫 和s2.Event的先前狀態值s2.Ts
  • s1檢查 1 無關緊要,因為沒有上一個步驟,而且 檢查 2 未通過,因為記錄不符合 的條件 Event == "Start"

step m_id s1.Ts s1.事件 s2.Ts s2.事件 s3.Ts s3.事件
s1 X X X X
s2 0 00:01:00 “Start” 00:03:00 "D" X X
S3

記錄 5

Ts 活動
4m “Stop”

記錄每個步驟的評估:

  • s3檢查 1 是通過,因為 s2 是空的,而且符合 s3 的條件 Event == "Stop"。 此比對會導致 清除的狀態 s2 ,並將中的 s2 序列升階為 s3記錄 5 及其 m_id0) 會新增至狀態和輸出。
  • s2檢查 1 不會通過,因為 的狀態 s1 是空的,而且 檢查 2 未通過,因為 s2 缺少作用中的序列。
  • s1檢查 1 無關緊要,因為沒有上一個步驟。 檢查 2 未通過,因為記錄不符合 的條件 Event == "Start"

step m_id s1.Ts s1.事件 s2.Ts s2.事件 s3.Ts s3.事件
s1 X X X X
s2 X X
S3 0 00:01:00 “Start” 00:03:00 "D" 00:04:00 “Stop”

記錄 6

Ts 活動
6m “C”

記錄每個步驟的評估:

  • s3檢查 1 不會通過,因為 的狀態s2是空的,而且檢查 2 未通過s3,因為 s3 不符合 的條件Event == "Stop"
  • s2檢查 1 不會通過,因為 的狀態 s1 是空的,而且 檢查 2 未通過,因為 s2 缺少作用中的序列。
  • s1檢查 1 未通過,因為沒有上一個步驟,而且 檢查 2 未通過,因為它不符合 的條件 Event == "Start"記錄 6 會捨棄,而不會影響狀態或輸出。

step m_id s1.Ts s1.事件 s2.Ts s2.事件 s3.Ts s3.事件
s1 X X X X
s2 X X
S3 0 00:01:00 “Start” 00:03:00 "D" 00:04:00 “Stop”

記錄 7

Ts 活動
8m “Start”

記錄每個步驟的評估:

  • s3檢查 1 不會通過,因為 的狀態 s2 是空的,而且 檢查 2 未通過,因為它不符合 的條件 Event == "Stop"
  • s2檢查 1 不會通過,因為 的狀態 s1 是空的,而且 檢查 2 未通過,因為 s2 缺少作用中的序列。
  • s1檢查 1 未通過,因為沒有上一個步驟。 它會通過 Check 2 ,因為它符合 的條件 Event == "Start"。 此比對會使用新的 ,在 中 s1 起始新的 m_id序列。 記錄 7 及其 m_id1) 會新增至狀態和輸出。

step m_id s1.Ts s1.事件 s2.Ts s2.事件 s3.Ts s3.事件
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”

注意

狀態中現在有兩個作用中序列。

記錄8

Ts 活動
11m “E”

記錄每個步驟的評估:

  • s3檢查 1 不會通過,因為 的狀態 s2 是空的,而且 檢查 2 未通過 s3 ,因為它不符合 的條件 Event == "Stop"
  • s2檢查 1 是傳遞的,因為 的狀態 s1 是空的,且記錄符合 的條件 Ts - s1.Ts < 5m。 此比對會導致 清除的狀態 s1 ,並將中的 s1 序列升階為 s2記錄 8 及其 m_id1) 會新增至狀態和輸出。
  • s1檢查 1 無關緊要,因為沒有上一個步驟,而且 檢查 2 未通過,因為記錄不符合 的條件 Event == "Start"

step m_id s1.Ts s1.事件 s2.Ts s2.事件 s3.Ts s3.事件
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”

記錄 9

Ts 活動
12m “Stop”

記錄每個步驟的評估:

  • s3檢查 1 是通過,因為 s2 是空的,而且符合 s3 的條件 Event == "Stop"。 此比對會導致 清除的狀態 s2 ,並將中的 s2 序列升階為 s3記錄 9 及其 m_id1) 會新增至狀態和輸出。
  • s2檢查 1 不會通過,因為 的狀態 s1 是空的,而且 檢查 2 未通過,因為 s2 缺少作用中的序列。
  • s1檢查 1 未通過,因為沒有上一個步驟。 它會通過 Check 2 ,因為它符合 的條件 Event == "Start"。 此比對會使用新的 ,在 中 s1 起始新的 m_id序列。

step m_id s1.Ts s1.事件 s2.Ts s2.事件 s3.Ts s3.事件
s1 X X X X
s2 X X
S3 1 00:08:00 “Start” 00:11:00 “E” 00:12:00 “Stop”

最終輸出

Ts 活動 m_id
00:01:00 啟動 0
00:02:00 B 0
00:03:00 D 0
00:04:00 停止 0
00:08:00 啟動 1
00:11:00 E 1
00:12:00 停止 1