scan 演算子
適用対象: ✅Microsoft Fabric✅Azure データ エクスプローラー✅Azure Monitor✅Microsoft Sentinel
述語に基づいてデータをスキャンし、照合し、シーケンスを構築します。
一致するレコードは、演算子のステップで定義されている述語に従って決まります。 述語は、前のステップで生成された状態によって異なる場合があります。 一致するレコードの出力は、入力レコードと、演算子のステップで定義されている割り当てによって決まります。
構文
T | scan
[ with_match_id
=
MatchIdColumnName ] [ declare
(
ColumnDeclarations )
] with
(
StepDefinitions )
ColumnDeclarations の構文
ColumnName :
ColumnType[=
DefaultValue ] [,
... ]
StepDefinition の構文
step
StepName [ output
= all
| last
| none
] :
Condition [ =>
Column =
Assignment [,
... ] ];
構文規則について詳しく知る。
パラメーター
件名 | タイプ | Required | 説明 |
---|---|---|---|
T | string |
✔️ | 入力表形式のソース。 |
MatchIdColumnName | string |
スキャン実行の一部として出力に追加される long 型の列の名前。 レコードの一致の 0 から始まるインデックスを示します。 |
|
ColumnDeclarations | string |
T のスキーマの拡張機能を宣言します。これらの列には、手順で値が割り当てられます。 割り当てられない場合は、 DefaultValue が返されます。 特に指定しない限り、 DefaultValue は null 。 |
|
StepName | string |
✔️ | 条件と割り当てのスキャン状態の値を参照するために使用されます。 ステップ名は一意である必要があります。 |
Condition | string |
✔️ | ステップに一致する入力のレコードを定義する true または false に評価される式。 レコードは、条件がステップの状態または前のステップの状態と true されたときにステップと一致します。 |
譲渡 | string |
レコードがステップと一致したときに対応する列に割り当てられるスカラー式。 | |
output |
string |
繰り返し一致するステップの出力ロジックを制御します。 all は、ステップに一致するすべてのレコードを出力 last 、ステップに対して一連の繰り返し一致の最後のレコードのみを出力し、 none はステップに一致するレコードを出力しません。 既定値は、all です。 |
返品
入力からステップへのレコードが一致するたびに 1 つのレコード。 出力のスキーマは、declare
句の列で拡張されたソースのスキーマです。
スキャン ロジック
scan
は、各ステップの現在の状態を考慮しながら、シリアル化された入力データをレコードごとに処理し、各レコードを各ステップと比較していきます。
都道府県
scan
演算子の基になる状態は、各step
の行を含むテーブルと考えることができます。 各ステップは、列の最新の値と、前のすべてのステップと現在のステップから宣言された変数を使用して、独自の状態を維持します。 関連する場合は、進行中のシーケンスの一致 ID も保持されます。
スキャン演算子に s_1、s_2、...、s_n という名前のステップがある場合、ステップ s_kは、s_1、s_2、...、s_kに対応するkレコードの状態になります。 StepName.ColumnName 形式は、状態の値を参照するために使用されます。 たとえば、s_2.col1
は、s_kの状態のステップ s_2に属する列col1
を参照します。 詳細な例については、 scan ロジックのチュートリアルを参照してください。
状態は空になり、スキャンされた入力レコードがステップと一致するたびに更新されます。 現在のステップの状態が空でない場合、ステップは 非アクティブなシーケンスを持つと呼ばれます。
一致するロジック
各入力レコードは、最後のステップから最初のステップまで、すべてのステップに対して逆の順序で評価されます。 レコード r が何らかのステップ s_kに対して評価されると、次のロジックが適用されます。
1: 前の手順 (s_k-1) の状態が空でない場合、rがs_kのConditionを満たしている場合は、一致が発生します。 一致すると、次のアクションが実行されます。
- s_kの状態がクリアされます。
- s_k-1の状態がs_kの状態になるように昇格されます。
- s_kの割り当てが計算され、rが拡張されます。
- 拡張 r が出力と s_kの状態に追加されます。
Note
Check 1が一致した場合、Check 2は無視され、rはs_k-1に対して評価されます。
チェック 2: s_kの状態にアクティブなシーケンスまたはs_kが最初のステップであり、rがs_kのConditionを満たしている場合は、一致が発生します。 一致すると、次のアクションが実行されます。
- s_kの割り当てが計算され、rが拡張されます。
- s_kの状態のs_kを表す値は、拡張rの値に置き換えられます。
- s_kが
output=all
として定義されている場合、拡張rが出力に追加されます。 - s_kが最初の手順である場合、新しいシーケンスが開始され、一致 ID が
1
増加します。 これは、with_match_id
が使用されている場合にのみ出力に影響します。
s_kのチェックが完了すると、rはs_k-1 に対して評価されます。
このロジックの詳細な例については、 scan ロジックのチュートリアルを参照してください。
例
累積合計
入力列の累積合計を計算します。 この例の結果は、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 | 1 |
2 | 3 |
3 | 6 |
4 | 10 |
5 | 15 |
リセット条件を持つ複数の列の累積合計
2 つの入力列の累積合計を計算し、累積合計が 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 | 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 分後に終了し、その後、新しいセッションが開始されます。 scanの個別の一致 (セッション) ごとに一意の値を割り当てるwith_match_id
フラグの使用に注意してください。 また、この例の 2 つの "ステップ" の特殊な使い方にも注意してください。inSession
には条件として true
が指定されているため、入力のすべてのレコードがキャプチャおよび出力される一方、現在の一致の sessionStart
値から 30 分過ぎてから発生するレコードが endSession
によってキャプチャされます。 endSession
ステップには、出力レコードを生成しないことを意味する output=none
が指定されています。 endSession
ステップを使用して、現在の一致の状態を inSession
から endSession
に進めることで、現在のレコードから始まる新しい一致 (セッション) を開始できます。
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 | 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 |
開始と終了の間のイベント
イベント Start
とイベント Stop
の間で、5 分以内に発生するイベントのシーケンスをすべて検索します。 各シーケンスに一致 ID を割り当てます。
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 | Event | 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 |
イベントのカスタム ファネルを計算する
イベント間の時間に関するカスタムしきい値 (1h
以内の Tornado
および 2h
以内の Thunderstorm Wind
) を使用して、State
ごとに Hail
->Tornado
->Thunderstorm Wind
というシーケンスのファネル完了率を計算します。 この例は 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 |
Tornado | 34 |
雷雨風 | 32 |
スキャン ロジックのチュートリアル
このセクションでは start と stop の間の Events のステップ バイ ステップ チュートリアルを使用したスキャン ロジック例を示します。
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
演算子の状態は、各ステップの行を含むテーブルと考えてください。各ステップには独自の状態があります。 この状態には、前のすべての手順と現在のステップの列と宣言された変数の最新の値が含まれます。 詳細については、「 State」を参照してください。
この例では、状態は次の表で表すことができます。
ステップ | m_id | s1.Ts | s1.出来事 | s2.Ts | s2.出来事 | s3.Ts | s3.出来事 |
---|---|---|---|---|---|---|---|
s1 | x | X | X | x | |||
s2 | x | x | |||||
s3 |
"X" は、特定のフィールドがそのステップとは無関係であることを示します。
一致するロジック
このセクションでは、Events
テーブルの各レコードを照合ロジックに従って、各ステップでの状態と出力の変換について説明します。
Note
入力レコードは、最後のステップ (s3
) から最初のステップ (s1
) まで、ステップに対して逆の順序で評価されます。
レコード 1
Ts | Event |
---|---|
0m | "A" |
各ステップで評価を記録します。
s3
: Check 1 はs2
の状態が空であるため渡されず、 Check 2 はアクティブなシーケンスがないためs3
渡されません。s2
: Check 1 はs1
の状態が空であるため渡されず、 Check 2 はアクティブなシーケンスがないためs2
渡されません。s1
: Check 1 は前の手順がないため、関係ありません。 レコードがEvent == "Start"
の条件を満たしていないため、チェック 2が渡されません。 レコード 1 は、状態や出力に影響を与えずに破棄されます。
状態:
ステップ | m_id | s1.Ts | s1.出来事 | s2.Ts | s2.出来事 | s3.Ts | s3.出来事 |
---|---|---|---|---|---|---|---|
s1 | x | X | X | x | |||
s2 | x | x | |||||
s3 |
レコード 2
Ts | Event |
---|---|
1 分 | "Start" |
各ステップで評価を記録します。
s3
: Check 1 はs2
の状態が空であるため渡されず、 Check 2 はアクティブなシーケンスがないためs3
渡されません。s2
: Check 1 はs1
の状態が空であるため渡されず、 Check 2 はアクティブなシーケンスがないためs2
渡されません。s1
: Check 1 は前の手順がないため、関係ありません。 レコードがEvent == "Start"
の条件を満たしているため、チェック 2 が渡されます。 この一致によって新しいシーケンスが開始され、m_id
が割り当てられます。 レコード 2 とそのm_id
(0
) が状態と出力に追加されます。
状態:
ステップ | 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 | Event |
---|---|
2m | "B" |
各ステップで評価を記録します。
s3
: Check 1 はs2
の状態が空であるため渡されず、 Check 2 はアクティブなシーケンスがないためs3
渡されません。s2
: Check 1 が渡されるのは、s1
の状態が空で、レコードがTs - s1.Ts < 5m
の条件を満たしているためです。 この一致により、s1
の状態がクリアされ、s1
のシーケンスがs2
に昇格されます。 レコード 3 とそのm_id
(0
) が状態と出力に追加されます。s1
: Check 1は前の手順がないため無関係であり、レコードがEvent == "Start"
の条件を満たしていないため、Check 2は渡されません。
状態:
ステップ | 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 | Event |
---|---|
3 分 | "D" |
各ステップで評価を記録します。
s3
: Check 1 はレコードがEvent == "Stop"
の条件を満たしていないため渡されず、 Check 2 はアクティブなシーケンスがないためs3
渡されません。s2
: Check 1s1
の状態が空であるため、は渡されません。Ts - s1.Ts < 5m
の条件を満たしているため、Check 2 を渡します。 レコード 4 とそのm_id
(0
) が状態と出力に追加されます。 このレコードの値は、s2.Ts
とs2.Event
の以前の状態値を上書きします。s1
: Check 1は前の手順がないため無関係であり、レコードがEvent == "Start"
の条件を満たしていないため、Check 2は渡されません。
状態:
ステップ | 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 | Event |
---|---|
4m | "Stop" |
各ステップで評価を記録します。
s3
: Check 1 が渡されるのは、s2
が空でないためで、Event == "Stop"
のs3
条件を満たしているためです。 この一致により、s2
の状態がクリアされ、s2
のシーケンスがs3
に昇格されます。 レコード 5 とそのm_id
(0
) が状態と出力に追加されます。s2
: Check 1 はs1
の状態が空であるため渡されず、 Check 2 はアクティブなシーケンスがないためs2
渡されません。s1
: Check 1 は前の手順がないため、関係ありません。 レコードがEvent == "Start"
の条件を満たしていないため、チェック 2が渡されません。
状態:
ステップ | 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 | Event |
---|---|
6 分 | "C" |
各ステップで評価を記録します。
s3
: Check 1はs2
の状態が空であるため渡されず、Check 2はs3
がEvent == "Stop"
のs3
条件を満たしていないため渡されません。s2
: Check 1 はs1
の状態が空であるため渡されず、 Check 2 はアクティブなシーケンスがないためs2
渡されません。s1
: Check 1 は前の手順がないため渡されず、 Check 2 はEvent == "Start"
の条件を満たしていないため渡されません。 レコード 6 は、状態や出力に影響を与えずに破棄されます。
状態:
ステップ | 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 | Event |
---|---|
8m | "Start" |
各ステップで評価を記録します。
s3
: Check 1 はs2
の状態が空であるため渡されず、 Check 2 はEvent == "Stop"
の条件を満たしていないため渡されません。s2
: Check 1 はs1
の状態が空であるため渡されず、 Check 2 はアクティブなシーケンスがないためs2
渡されません。s1
: Check 1 は前の手順がないため渡されません。Event == "Start"
の条件を満たしているため、Check 2 を渡します。 この一致により、新しいm_id
でs1
で新しいシーケンスが開始されます。 レコード 7 とそのm_id
(1
) が状態と出力に追加されます。
状態:
ステップ | 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" |
Note
現在、状態に 2 つのアクティブ なシーケンスがあります。
レコード 8
Ts | Event |
---|---|
11m | "E" |
各ステップで評価を記録します。
s3
: Check 1はs2
の状態が空であるため渡されず、Event == "Stop"
のs3
条件を満たしていないため、Check 2 は渡されません。s2
: Check 1 が渡されるのは、s1
の状態が空で、レコードがTs - s1.Ts < 5m
の条件を満たしているためです。 この一致により、s1
の状態がクリアされ、s1
のシーケンスがs2
に昇格されます。 レコード 8 とそのm_id
(1
) が状態と出力に追加されます。s1
: Check 1は前の手順がないため無関係であり、レコードがEvent == "Start"
の条件を満たしていないため、Check 2は渡されません。
状態:
ステップ | 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 | Event |
---|---|
12m | "Stop" |
各ステップで評価を記録します。
s3
: Check 1 が渡されるのは、s2
が空でないためで、Event == "Stop"
のs3
条件を満たしているためです。 この一致により、s2
の状態がクリアされ、s2
のシーケンスがs3
に昇格されます。 レコード 9 とそのm_id
(1
) が状態と出力に追加されます。s2
: Check 1 はs1
の状態が空であるため渡されず、 Check 2 はアクティブなシーケンスがないためs2
渡されません。s1
: Check 1 は前の手順がないため渡されません。Event == "Start"
の条件を満たしているため、Check 2 を渡します。 この一致により、新しいm_id
でs1
で新しいシーケンスが開始されます。
状態:
ステップ | 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 | Event | 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 |