次の方法で共有


scan 演算子

適用対象: ✅Microsoft FabricAzure データ エクスプローラーAzure MonitorMicrosoft Sentinel

述語に基づいてデータをスキャンし、照合し、シーケンスを構築します。

一致するレコードは、演算子のステップで定義されている述語に従って決まります。 述語は、前のステップで生成された状態によって異なる場合があります。 一致するレコードの出力は、入力レコードと、演算子のステップで定義されている割り当てによって決まります。

構文

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

ColumnDeclarations の構文

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

StepDefinition の構文

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

構文規則について詳しく知る。

パラメーター

件名 タイプ Required 説明
T string ✔️ 入力表形式のソース。
MatchIdColumnName string スキャン実行の一部として出力に追加される long 型の列の名前。 レコードの一致の 0 から始まるインデックスを示します。
ColumnDeclarations string T のスキーマの拡張機能を宣言します。これらの列には、手順で値が割り当てられます。 割り当てられない場合は、 DefaultValue が返されます。 特に指定しない限り、 DefaultValuenull
StepName string ✔️ 条件と割り当てのスキャン状態の値を参照するために使用されます。 ステップ名は一意である必要があります。
Condition string ✔️ ステップに一致する入力のレコードを定義する true または false に評価される式。 レコードは、条件がステップの状態または前のステップの状態と true されたときにステップと一致します。
譲渡 string レコードがステップと一致したときに対応する列に割り当てられるスカラー式。
output string 繰り返し一致するステップの出力ロジックを制御します。 all は、ステップに一致するすべてのレコードを出力 last 、ステップに対して一連の繰り返し一致の最後のレコードのみを出力し、 none はステップに一致するレコードを出力しません。 既定値は、all です。

返品

入力からステップへのレコードが一致するたびに 1 つのレコード。 出力のスキーマは、declare 句の列で拡張されたソースのスキーマです。

スキャン ロジック

scan は、各ステップの現在の状態を考慮しながら、シリアル化された入力データをレコードごとに処理し、各レコードを各ステップと比較していきます。

都道府県

scan演算子の基になる状態は、各stepの行を含むテーブルと考えることができます。 各ステップは、列の最新の値と、前のすべてのステップと現在のステップから宣言された変数を使用して、独自の状態を維持します。 関連する場合は、進行中のシーケンスの一致 ID も保持されます。

スキャン演算子に s_1s_2、...、s_n という名前のステップがある場合、ステップ s_kは、s_1s_2、...、s_kに対応するkレコードの状態になります。 StepName.ColumnName 形式は、状態の値を参照するために使用されます。 たとえば、s_2.col1は、s_kの状態のステップ s_2に属する列col1を参照します。 詳細な例については、 scan ロジックのチュートリアルを参照してください。

状態は空になり、スキャンされた入力レコードがステップと一致するたびに更新されます。 現在のステップの状態が空でない場合、ステップは 非アクティブなシーケンスを持つと呼ばれます。

一致するロジック

各入力レコードは、最後のステップから最初のステップまで、すべてのステップに対して逆の順序で評価されます。 レコード r が何らかのステップ s_kに対して評価されると、次のロジックが適用されます。

  • 1: 前の手順 (s_k-1) の状態が空でない場合、rs_kConditionを満たしている場合は、一致が発生します。 一致すると、次のアクションが実行されます。

    1. s_kの状態がクリアされます。
    2. s_k-1の状態がs_kの状態になるように昇格されます。
    3. s_kの割り当てが計算され、rが拡張されます。
    4. 拡張 r が出力と s_kの状態に追加されます。

    Note

    Check 1が一致した場合、Check 2は無視され、rs_k-1に対して評価されます。

  • チェック 2: s_kの状態にアクティブなシーケンスまたはs_kが最初のステップであり、rs_kConditionを満たしている場合は、一致が発生します。 一致すると、次のアクションが実行されます。

    1. s_kの割り当てが計算され、rが拡張されます。
    2. s_kの状態のs_kを表す値は、拡張rの値に置き換えられます。
    3. s_koutput=allとして定義されている場合、拡張rが出力に追加されます。
    4. s_kが最初の手順である場合、新しいシーケンスが開始され、一致 ID が1増加します。 これは、with_match_id が使用されている場合にのみ出力に影響します。

s_kのチェックが完了すると、rs_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 1s2 の状態が空であるため渡されず、 Check 2 はアクティブなシーケンスがないため s3 渡されません。
  • s2: Check 1s1 の状態が空であるため渡されず、 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 1s2 の状態が空であるため渡されず、 Check 2 はアクティブなシーケンスがないため s3 渡されません。
  • s2: Check 1s1 の状態が空であるため渡されず、 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 1s2 の状態が空であるため渡されず、 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.Tss2.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 1s1 の状態が空であるため渡されず、 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 1s2の状態が空であるため渡されず、Check 2s3Event == "Stop"s3条件を満たしていないため渡されません。
  • s2: Check 1s1 の状態が空であるため渡されず、 Check 2 はアクティブなシーケンスがないため s2 渡されません。
  • s1: Check 1 は前の手順がないため渡されず、 Check 2Event == "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 1s2 の状態が空であるため渡されず、 Check 2Event == "Stop"の条件を満たしていないため渡されません。
  • s2: Check 1s1 の状態が空であるため渡されず、 Check 2 はアクティブなシーケンスがないため s2 渡されません。
  • s1: Check 1 は前の手順がないため渡されません。 Event == "Start"の条件を満たしているため、Check 2 を渡します。 この一致により、新しいm_ids1で新しいシーケンスが開始されます。 レコード 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 1s2の状態が空であるため渡されず、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 1s1 の状態が空であるため渡されず、 Check 2 はアクティブなシーケンスがないため s2 渡されません。
  • s1: Check 1 は前の手順がないため渡されません。 Event == "Start"の条件を満たしているため、Check 2 を渡します。 この一致により、新しいm_ids1で新しいシーケンスが開始されます。

状態:

ステップ 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