다음을 통해 공유


scan 연산자

적용 대상: ✅Microsoft Fabric✅Azure Data ExplorerAzure MonitorMicrosoft Sentinel

조건자를 기준으로 데이터를 검사하고, 일치시키고, 시퀀스를 빌드합니다.

일치 레코드는 연산자의 단계에 정의된 조건자에 따라 결정됩니다. 조건자는 이전 단계에서 생성된 상태에 따라 달라질 수 있습니다. 일치하는 레코드의 출력은 연산자의 단계에 정의된 입력 레코드 및 할당에 의해 결정됩니다.

구문

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

ColumnDeclarations 구문

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

StepDefinition 구문

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

구문 규칙에 대해 자세히 알아봅니다.

매개 변수

이름 Type 필수 설명
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입니다.

반품

입력에서 단계로 레코드의 각 일치 항목에 대한 레코드입니다. 출력의 스키마는 절의 열로 확장된 원본의 스키마입니다 declare .

검사 논리

scan 는 각 단계의 현재 상태를 고려하면서 각 단계의 조건과 각 레코드를 비교하여 레코드별로 직렬화된 입력 데이터를 통해 이동합니다.

State(상태)

연산자의 scan 기본 상태는 각각 step에 대한 행이 있는 테이블로 간주할 수 있습니다. 각 단계에서는 열의 최신 값과 이전 단계 및 현재 단계의 선언된 변수를 사용하여 자체 상태를 유지합니다. 관련된 경우 진행 중인 시퀀스에 대한 일치 ID도 보유합니다.

검사 연산자에 s_1, s_2, ...라는 n 단계가 있는 경우 s_n 단계 s_k s_1, s_2, ..., s_k 해당하는 상태에 k 레코드가 있습니다. StepName입니다.ColumnName 형식은 상태의 값을 참조하는 데 사용됩니다. 예를 들어 s_k s_2.col1 상태의 단계 s_2 속하는 열을 col1 참조합니다. 자세한 예제는 검사 논리 연습을 참조 하세요.

상태는 빈 상태로 시작되고 검색된 입력 레코드가 단계와 일치할 때마다 업데이트됩니다. 현재 단계의 상태가 비어 있지 않으면 이 단계를 활성 시퀀스라고 합니다.

일치하는 논리

각 입력 레코드는 마지막 단계에서 첫 번째 단계까지 모든 단계에 대해 역순으로 평가됩니다. 레코드 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 정의된 경우 확장 r이 출력에 추가output=all됩니다.
    4. s_k 첫 번째 단계이면 새 시퀀스가 시작되고 일치 ID가 증가합니다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 6
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(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 각 고유 일치(세션)에 대해 고유한 값을 할당하는 플래그를 사용합니다. 또한 이 예제 inSession 에서 두 단계의 특별한 사용은 true 조건으로 사용되므로 현재 일치 값에서 30m 이상 발생하는 레코드를 캡처하는 동안 endSession 입력의 sessionStart 모든 레코드를 캡처하고 출력합니다. 이 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(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

시작과 중지 사이의 이벤트

이벤트와 5분 이내에 발생하는 이벤트 Start 사이의 모든 이벤트 Stop 시퀀스를 찾습니다. 각 시퀀스에 대한 일치 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(Ts) 이벤트 m_id
00:01:00 Start 0
00:02:00 B 0
00:03:00 D 0
00:04:00 중지 0
00:08:00 Start 1
00:11:00 E 1
00:12:00 중지 1

이벤트의 사용자 지정 깔때기 계산

이벤트(내 1hThunderstorm Wind2h) 사이의 시간에 대한 사용자 지정 임계값을 사용하여 시퀀스의>HailTornadoThunderstorm Wind>State 깔때기형 완성을 계산합니다.Tornado 이 예제는 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
Hail 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 상태를 각 단계마다 행이 있는 테이블로 간주합니다. 각 단계에는 고유한 상태가 있습니다. 이 상태에는 이전 단계와 현재 단계의 모든 열 및 선언된 변수의 최신 값이 포함됩니다. 자세한 내용은 State를 참조하세요.

이 예제에서는 다음 표와 함께 상태를 나타낼 수 있습니다.

step m_id s1. Ts(Ts) s1. 이벤트 s2. Ts(Ts) s2. 이벤트 s3. Ts(Ts) s3. 이벤트
s1 X X X X
s2 X X
s3

"X"는 특정 필드가 해당 단계와 관련이 없음을 나타냅니다.

일치하는 논리

이 섹션에서는 테이블의 각 레코드를 통해 일치하는 논리Events 따라 각 단계에서 상태 및 출력의 변환을 설명합니다.

참고 항목

입력 레코드는 마지막 단계()부터 첫 번째s1 단계(s3)에 이르는 단계의 역순으로 평가됩니다.

레코드 1

Ts(Ts) 이벤트
0m "A"

각 단계에서 평가를 기록합니다.

  • s3: 상태가 s2 비어 있으므로 Check 1이 전달되지 않고 활성 시퀀스가 없기 때문에 s3 Check 2가 전달되지 않습니다.
  • s2: 상태가 s1 비어 있으므로 Check 1이 전달되지 않고 활성 시퀀스가 없기 때문에 s2 Check 2가 전달되지 않습니다.
  • s1: 이전 단계가 없으므로 1 이 관련이 없는지 확인합니다. 레코드가 조건을 충족하지 않으므로 Check 2Event == "Start"전달되지 않습니다. 레코드 1 은 상태 또는 출력에 영향을 주지 않고 삭제됩니다.

State:

step m_id s1. Ts(Ts) s1. 이벤트 s2. Ts(Ts) s2. 이벤트 s3. Ts(Ts) s3. 이벤트
s1 X X X X
s2 X X
s3

레코드 2

Ts(Ts) 이벤트
1분 "시작"

각 단계에서 평가를 기록합니다.

  • s3: 상태가 s2 비어 있으므로 Check 1이 전달되지 않고 활성 시퀀스가 없기 때문에 s3 Check 2가 전달되지 않습니다.
  • s2: 상태가 s1 비어 있으므로 Check 1이 전달되지 않고 활성 시퀀스가 없기 때문에 s2 Check 2가 전달되지 않습니다.
  • s1: 이전 단계가 없으므로 1 이 관련이 없는지 확인합니다. 레코드가 조건을 충족하므로 Check 2Event == "Start"전달됩니다. 이 일치 항목은 새 시퀀스를 시작하고 m_id 할당됩니다. 레코드 2 와 해당 m_id (0)가 상태 및 출력에 추가됩니다.

State:

step m_id s1. Ts(Ts) s1. 이벤트 s2. Ts(Ts) s2. 이벤트 s3. Ts(Ts) s3. 이벤트
s1 0 00:01:00 "시작" X X X X
s2 X X
s3

레코드 3

Ts(Ts) 이벤트
2m “B”

각 단계에서 평가를 기록합니다.

  • s3: 상태가 s2 비어 있으므로 Check 1이 전달되지 않고 활성 시퀀스가 없기 때문에 s3 Check 2가 전달되지 않습니다.
  • s2: 상태가 s1 비어 있지 않으며 레코드가 조건을 충족하므로 Check 1Ts - s1.Ts < 5m전달됩니다. 이 일치 항목으로 인해 상태가 s1 지워지고 시퀀스가 s1 승격됩니다 s2. 레코드 3 및 해당 m_id (0)가 상태 및 출력에 추가됩니다.
  • s1: 이전 단계가 없으므로 Check 1은 관련이 없으며 레코드가 조건을 Event == "Start"충족하지 않으므로 Check 2가 전달되지 않습니다.

State:

step m_id s1. Ts(Ts) s1. 이벤트 s2. Ts(Ts) s2. 이벤트 s3. Ts(Ts) s3. 이벤트
s1 X X X X
s2 0 00:01:00 "시작" 00:02:00 “B” X X
s3

레코드 4

Ts(Ts) 이벤트
3개월 "D"

각 단계에서 평가를 기록합니다.

  • s3: 레코드가 조건을 Event == "Stop"충족하지 않으므로 Check 1이 전달되지 않으며 활성 시퀀스가 없기 때문에 s3 Check 2가 전달되지 않습니다.
  • s2: 상태가 s1 비어 있으므로 Check 1이 전달되지 않습니다. 의 조건을 Ts - s1.Ts < 5m충족하므로 Check 2를 전달합니다. 레코드 4 및 해당 m_id (0)가 상태 및 출력에 추가됩니다. 이 레코드의 값은 이전 상태 값을 s2.Ts 덮어쓰고 s2.Event.
  • s1: 이전 단계가 없으므로 Check 1은 관련이 없으며 레코드가 조건을 Event == "Start"충족하지 않으므로 Check 2가 전달되지 않습니다.

State:

step m_id s1. Ts(Ts) s1. 이벤트 s2. Ts(Ts) s2. 이벤트 s3. Ts(Ts) s3. 이벤트
s1 X X X X
s2 0 00:01:00 "시작" 00:03:00 "D" X X
s3

레코드 5

Ts(Ts) 이벤트
4m "중지"

각 단계에서 평가를 기록합니다.

  • s3: 1이(가) 비어 있지 않아서 1s3 전달 s2 되고 해당 조건이 Event == "Stop"충족됩니다. 이 일치 항목으로 인해 상태가 s2 지워지고 시퀀스가 s2 승격됩니다 s3. 레코드 5 및 해당 m_id (0)가 상태 및 출력에 추가됩니다.
  • s2: 상태가 s1 비어 있으므로 Check 1이 전달되지 않고 활성 시퀀스가 없기 때문에 s2 Check 2가 전달되지 않습니다.
  • s1: 이전 단계가 없으므로 1 이 관련이 없는지 확인합니다. 레코드가 조건을 충족하지 않으므로 Check 2Event == "Start"전달되지 않습니다.

State:

step m_id s1. Ts(Ts) s1. 이벤트 s2. Ts(Ts) s2. 이벤트 s3. Ts(Ts) s3. 이벤트
s1 X X X X
s2 X X
s3 0 00:01:00 "시작" 00:03:00 "D" 00:04:00 "중지"

레코드 6

Ts(Ts) 이벤트
6m "C"

각 단계에서 평가를 기록합니다.

  • s3: 상태가 s2 비어 있으므로 Check 1이 전달되지 않고 Check 2가 조건을 Event == "Stop"충족 s3 하지 않으므로 전달 s3 되지 않습니다.
  • s2: 상태가 s1 비어 있으므로 Check 1이 전달되지 않고 활성 시퀀스가 없기 때문에 s2 Check 2가 전달되지 않습니다.
  • s1: 이전 단계가 없으므로 Check 1 이 전달되지 않으며 Check 2 가 조건을 Event == "Start"충족하지 않으므로 전달되지 않습니다. 레코드 6 은 상태 또는 출력에 영향을 주지 않고 삭제됩니다.

State:

step m_id s1. Ts(Ts) s1. 이벤트 s2. Ts(Ts) s2. 이벤트 s3. Ts(Ts) s3. 이벤트
s1 X X X X
s2 X X
s3 0 00:01:00 "시작" 00:03:00 "D" 00:04:00 "중지"

레코드 7

Ts(Ts) 이벤트
8m "시작"

각 단계에서 평가를 기록합니다.

  • s3: 상태가 s2 비어 있으므로 Check 1이 전달되지 않고 Check 2가 조건을 Event == "Stop"충족하지 않으므로 전달되지 않습니다.
  • s2: 상태가 s1 비어 있으므로 Check 1이 전달되지 않고 활성 시퀀스가 없기 때문에 s2 Check 2가 전달되지 않습니다.
  • s1: 이전 단계가 없으므로 Check 1 이 전달되지 않습니다. 의 조건을 Event == "Start"충족하므로 Check 2를 전달합니다. 이 일치 항목은 새 시퀀스를 사용하여 새 m_id시퀀스를 s1 시작합니다. 레코드 7 및 해당 m_id (1)가 상태 및 출력에 추가됩니다.

State:

step m_id s1. Ts(Ts) s1. 이벤트 s2. Ts(Ts) s2. 이벤트 s3. Ts(Ts) s3. 이벤트
s1 1 00:08:00 "시작" X X X X
s2 X X
s3 0 00:01:00 "시작" 00:03:00 "D" 00:04:00 "중지"

참고 항목

이제 상태에 두 개의 활성 시퀀스가 있습니다.

레코드 8

Ts(Ts) 이벤트
11m "E"

각 단계에서 평가를 기록합니다.

  • s3: 상태가 s2 비어 있으므로 Check 1이 전달되지 않고 Check 2가 조건을 Event == "Stop"충족 s3 하지 않으므로 전달되지 않습니다.
  • s2: 상태가 s1 비어 있지 않으며 레코드가 조건을 충족하므로 Check 1Ts - s1.Ts < 5m전달됩니다. 이 일치 항목으로 인해 상태가 s1 지워지고 시퀀스가 s1 승격됩니다 s2. 레코드 8 및 해당 m_id (1)가 상태 및 출력에 추가됩니다.
  • s1: 이전 단계가 없으므로 Check 1은 관련이 없으며 레코드가 조건을 Event == "Start"충족하지 않으므로 Check 2가 전달되지 않습니다.

State:

step m_id s1. Ts(Ts) s1. 이벤트 s2. Ts(Ts) s2. 이벤트 s3. Ts(Ts) s3. 이벤트
s1 X X X X
s2 1 00:08:00 "시작" 00:11:00 "E" X X
s3 0 00:01:00 "시작" 00:03:00 "D" 00:04:00 "중지"

레코드 9

Ts(Ts) 이벤트
12m "중지"

각 단계에서 평가를 기록합니다.

  • s3: 1이(가) 비어 있지 않아서 1s3 전달 s2 되고 해당 조건이 Event == "Stop"충족됩니다. 이 일치 항목으로 인해 상태가 s2 지워지고 시퀀스가 s2 승격됩니다 s3. 레코드 9 및 해당 m_id (1)가 상태 및 출력에 추가됩니다.
  • s2: 상태가 s1 비어 있으므로 Check 1이 전달되지 않고 활성 시퀀스가 없기 때문에 s2 Check 2가 전달되지 않습니다.
  • s1: 이전 단계가 없으므로 Check 1 이 전달되지 않습니다. 의 조건을 Event == "Start"충족하므로 Check 2를 전달합니다. 이 일치 항목은 새 시퀀스를 사용하여 새 m_id시퀀스를 s1 시작합니다.

State:

step m_id s1. Ts(Ts) s1. 이벤트 s2. Ts(Ts) s2. 이벤트 s3. Ts(Ts) s3. 이벤트
s1 X X X X
s2 X X
s3 1 00:08:00 "시작" 00:11:00 "E" 00:12:00 "중지"

최종 출력

Ts(Ts) 이벤트 m_id
00:01:00 Start 0
00:02:00 B 0
00:03:00 D 0
00:04:00 중지 0
00:08:00 Start 1
00:11:00 E 1
00:12:00 중지 1