Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Aplica-se a: ✅Microsoft Fabric✅Azure Data Explorer✅Azure Monitor✅Microsoft Sentinel
Examina dados, faz a correspondência e cria sequências com base nos predicados.
Os registros correspondentes são determinados de acordo com os predicados definidos nas etapas do operador. Um predicado pode depender do estado gerado pelas etapas anteriores. A saída para o registro correspondente é determinada pelo registro de entrada e atribuições definidas nas etapas do operador.
Syntax
T| scan [ with_match_id=MatchIdColumnName ] [ declare(ColumnDeclarations) ] with(StepDefinitions)
Sintaxe ColumnDeclarations
Columnname:ColumnType[=DefaultValue ] [, ... ]
Sintaxe StepDefinition
step
StepName [ output | lastall | none = ] :Condition [ =>Column=Assignment [, ... ] ];
Saiba mais sobre convenções de sintaxe.
Parameters
| Name | Tipo | Required | Description |
|---|---|---|---|
| T | string |
✔️ | A fonte tabular de entrada. |
| MatchIdColumnName | string |
O nome de uma coluna do tipo long que é acrescentada à saída como parte da execução da verificação. Indica o índice baseado em 0 da correspondência para o registro. |
|
| ColumnDeclarations | string |
Declara uma extensão para o esquema de T. Essas colunas são valores atribuídos nas etapas. Se não for atribuído, o DefaultValue será retornado. A menos que especificado de outra forma, DefaultValue será null. |
|
| StepName | string |
✔️ | Usado para referenciar valores no estado de verificação para condições e atribuições. O nome da etapa deve ser exclusivo. |
| Condition | string |
✔️ | Uma expressão que avalia true ou false define quais registros da entrada correspondem à etapa. Um registro corresponde à etapa quando a condição está true com o estado da etapa ou com o estado da etapa anterior. |
| Assignment | string |
Uma expressão escalar que é atribuída à coluna correspondente quando um registro corresponde a uma etapa. | |
output |
string |
Controla a lógica de saída da etapa em correspondências repetidas.
all gera todos os registros que correspondem à etapa, last gera apenas o último registro em uma série de correspondências repetidas para a etapa e none não gera registros que correspondem à etapa. O padrão é all. |
Returns
Um registro para cada correspondência de um registro da entrada para uma etapa. O esquema da saída é o esquema da fonte estendida com a coluna na declare cláusula.
Lógica de verificação
scan examina os dados de entrada serializados, registro por registro, comparando cada registro com a condição de cada etapa, levando em consideração o estado atual de cada etapa.
State
O estado subjacente do scan operador pode ser pensado como uma tabela com uma linha para cada step. Cada etapa mantém seu próprio estado com os valores mais recentes das colunas e variáveis declaradas de todas as etapas anteriores e da etapa atual. Se relevante, ele também contém a ID de correspondência para a sequência em andamento.
Se um operador de verificação tiver n etapas denominadas s_1, s_2, ..., s_n então, a etapa s_k teria k registros em seu estado correspondente a s_1, s_2, ..., s_k. O StepName. O formato ColumnName é usado para fazer referência a um valor no estado. Por exemplo, s_2.col1 faria referência à coluna col1 que pertence à etapa s_2 no estado de s_k. Para obter um exemplo detalhado, consulte o passo a passo da lógica de verificação.
O estado começa vazio e é atualizado sempre que um registro de entrada digitalizado corresponde a uma etapa. Quando o estado da etapa atual não está vazio, a etapa é conhecida como tendo uma sequência ativa.
Lógica de correspondência
Cada registro de entrada é avaliado em relação a todas as etapas na ordem inversa, da última etapa à primeira. Quando um registro r é avaliado em relação a alguma etapa s_k, a seguinte lógica é aplicada:
Verifique 1: Se o estado da etapa anterior (s_k-1) não for inteiro e r atender à Condição de s_k, ocorrerá uma correspondência. A correspondência leva às seguintes ações:
- O estado de s_k está limpo.
- O estado de s_k-1 é promovido para se tornar o estado de s_k.
- As atribuições de s_k são calculadas e estendem r.
- O r estendido é adicionado à saída e ao estado de s_k.
Note
Se a Verificação 1 resultar em uma correspondência, a Verificação 2 será desconsiderada e r passará a ser avaliado em relação a s_k-1.
Verifique 2: Se o estado de s_k tiver uma sequência ativa ou s_k for a primeira etapa e r atender à Condição de s_k, ocorrerá uma correspondência. A correspondência leva às seguintes ações:
- As atribuições de s_k são calculadas e estendem r.
- Os valores que representam s_k no estado de s_k são substituídos pelos valores do r estendido.
- Se s_k for definido como
output=all, o r estendido será adicionado à saída. - Se s_k for a primeira etapa, uma nova sequência começará e a ID da correspondência aumentará
1. Isso afeta apenas a saída quandowith_match_idé usado.
Depois que as verificações de s_k estiverem concluídas, o r passará a ser avaliado em relação a s_k-1.
Para obter um exemplo detalhado dessa lógica, consulte o passo a passo da lógica de verificação.
Examples
O exemplo nesta seção mostra como usar a sintaxe para ajudá-lo a começar.
Os exemplos neste artigo usam tabelas disponíveis publicamente no cluster de ajuda, como a
StormEventstabela no banco de dados Exemplos .
Os exemplos neste artigo usam tabelas publicamente disponíveis, como a
Weathertabela na galeria de exemplos de análise de clima. Talvez seja necessário modificar o nome da tabela na consulta de exemplo para corresponder à tabela em seu workspace.
Soma cumulativa
Calcule a soma cumulativa de uma coluna de entrada. O resultado deste exemplo é equivalente ao uso de 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 |
Soma cumulativa em várias colunas com uma condição de redefinição
Calcule a soma cumulativa para duas colunas de entrada, redefina o valor da soma para o valor do registro atual sempre que a soma cumulativa atingir 10 ou mais.
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 |
Preencher uma coluna
Preencha uma coluna de string. Cada valor vazio recebe o último valor não vazio visto.
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 |
Marcação de sessões
Divida a entrada em sessões: uma sessão termina 30 minutos após o primeiro evento da sessão, após o qual uma nova sessão é iniciada. Observe o uso do with_match_id sinalizador, que atribui um valor exclusivo para cada correspondência distinta (sessão) da verificação. Observe também que o uso especial de duas etapas neste exemplo tem inSessiontrue como condição que captura e gera todos os registros da entrada enquanto endSession captura registros que ocorrem a mais de 30m do sessionStart valor da correspondência atual. A endSession etapa significa output=none que não produz registros de saída. A endSession etapa é usada para avançar o estado da correspondência atual de inSession para endSession, permitindo que uma nova correspondência (sessão) seja iniciada, a partir do registro atual.
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 |
Calculando o comprimento da sessão por usuário
Calcule a hora de início da sessão, a hora de término e a duração da sessão de cada usuário usando o scan operador. Uma sessão é definida como um período entre o logon de um usuário e o logoff subsequente. Combinando partition e scan com output=none e output=all, esse padrão garante que uma única linha seja retornada por sessão (ou seja, por par de logoff/logoff), em vez de uma linha por evento.
A lógica funciona por:
- Na etapa s1: Capturando o carimbo de data/hora de logon usando uma etapa de verificação com
output=none - Na etapa s2: emitindo uma linha somente quando um logoff correspondente é encontrado usando
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 |
Eventos entre Início e Parada
Encontre todas as sequências de eventos entre o evento Start e o evento Stop que ocorrem em 5 minutos. Atribua uma ID de correspondência para cada sequência.
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 |
Calcular um funil personalizado de eventos
Calcule uma conclusão de funil da sequência Hail ->Tornado ->Thunderstorm Wind com State limites personalizados nos tempos entre os eventos (Tornado dentro 1h e Thunderstorm Wind dentro 2h). Este exemplo é semelhante ao plug-in funnel_sequence_completion, mas permite maior flexibilidade.
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 |
| Ventos de tempestade | 32 |
Passo a passo da lógica de varredura
Esta seção demonstra a lógica de verificação usando um passo a passo dos Eventos entre o exemplo de início e parada :
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 |
O estado
Pense no estado do scan operador como uma tabela com uma linha para cada etapa, na qual cada etapa tem seu próprio estado. Esse estado contém os valores mais recentes das colunas e variáveis declaradas de todas as etapas anteriores e da etapa atual. Para saber mais, confira Estado.
Para este exemplo, o estado pode ser representado com a seguinte tabela:
| etapa | m_id | s1.Ts | s1.Event | s2.Ts | s2.Event | s3.Ts | s3.Event |
|---|---|---|---|---|---|---|---|
| s1 | X | X | X | X | |||
| s2 | X | X | |||||
| s3 |
O "X" indica que um campo específico é irrelevante para essa etapa.
A lógica de correspondência
Esta seção segue a lógica correspondente por meio de cada registro da Events tabela, explicando a transformação do estado e da saída em cada etapa.
Note
Um registro de entrada é avaliado em relação às etapas na ordem inversa, da última etapa (s3) à primeira etapa (s1).
Registro 1
| Ts | Event |
|---|---|
| 0m | "A" |
Registre a avaliação em cada etapa:
-
s3: a verificação 1 não é passada porque o estado estás2vazio e a Verificação 2 não é passada porques3falta uma sequência ativa. -
s2: a verificação 1 não é passada porque o estado estás1vazio e a Verificação 2 não é passada porques2falta uma sequência ativa. -
s1: a verificação 1 é irrelevante porque não há nenhuma etapa anterior. A verificação 2 não foi passada porque o registro não atende à condição deEvent == "Start". O registro 1 é descartado sem afetar o estado ou a saída.
State:
| etapa | m_id | s1.Ts | s1.Event | s2.Ts | s2.Event | s3.Ts | s3.Event |
|---|---|---|---|---|---|---|---|
| s1 | X | X | X | X | |||
| s2 | X | X | |||||
| s3 |
Registro 2
| Ts | Event |
|---|---|
| 1m | "Start" |
Registre a avaliação em cada etapa:
-
s3: a verificação 1 não é passada porque o estado estás2vazio e a Verificação 2 não é passada porques3falta uma sequência ativa. -
s2: a verificação 1 não é passada porque o estado estás1vazio e a Verificação 2 não é passada porques2falta uma sequência ativa. -
s1: a verificação 1 é irrelevante porque não há nenhuma etapa anterior. A verificação 2 é passada porque o registro atende à condição deEvent == "Start". Essa correspondência inicia uma nova sequência e ém_idatribuída. O registro 2 e seum_id(0) são adicionados ao estado e à saída.
State:
| etapa | 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 |
Registro 3
| Ts | Event |
|---|---|
| 2m | "B" |
Registre a avaliação em cada etapa:
-
s3: a verificação 1 não é passada porque o estado estás2vazio e a Verificação 2 não é passada porques3falta uma sequência ativa. -
s2: a verificação 1 é passada porque o estado nãos1está vazio e o registro atende à condição deTs - s1.Ts < 5m. Essa correspondência faz com que o estado des1seja limpo e a sequência ems1seja promovida paras2. O registro 3 e seum_id(0) são adicionados ao estado e à saída. -
s1: a verificação 1 é irrelevante porque não há nenhuma etapa anterior e a Verificação 2 não é passada porque o registro não atende à condição deEvent == "Start".
State:
| etapa | 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 |
Registro 4
| Ts | Event |
|---|---|
| 3m | "D" |
Registre a avaliação em cada etapa:
-
s3: a verificação 1 não é passada porque o registro não atende à condição deEvent == "Stop", e a Verificação 2 não é passada porques3não tem uma sequência ativa. -
s2: a verificação 1 não é passada porque o estado estás1vazio. Ele passa a Verificação 2 porque atende à condição deTs - s1.Ts < 5m. O registro 4 e seum_id(0) são adicionados ao estado e à saída. Os valores desse registro substituem os valores de estado anteriores paras2.Tses2.Event. -
s1: a verificação 1 é irrelevante porque não há nenhuma etapa anterior e a Verificação 2 não é passada porque o registro não atende à condição deEvent == "Start".
State:
| etapa | 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 |
Registro 5
| Ts | Event |
|---|---|
| 4m | "Stop" |
Registre a avaliação em cada etapa:
-
s3: a verificação 1 é passada porques2não está úmida e atende às3condição deEvent == "Stop". Essa correspondência faz com que o estado des2seja limpo e a sequência ems2seja promovida paras3. O registro 5 e seum_id(0) são adicionados ao estado e à saída. -
s2: a verificação 1 não é passada porque o estado estás1vazio e a Verificação 2 não é passada porques2falta uma sequência ativa. -
s1: a verificação 1 é irrelevante porque não há nenhuma etapa anterior. A verificação 2 não foi passada porque o registro não atende à condição deEvent == "Start".
State:
| etapa | 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" |
Registro 6
| Ts | Event |
|---|---|
| 6m | "C" |
Registre a avaliação em cada etapa:
-
s3: a verificação 1 não é passada porque o estado estás2vazio e a Verificação 2 não é passada porques3não atende às3condição deEvent == "Stop". -
s2: a verificação 1 não é passada porque o estado estás1vazio e a Verificação 2 não é passada porques2falta uma sequência ativa. -
s1: a verificação 1 não foi passada porque não há nenhuma etapa anterior e a Verificação 2 não é passada porque não atende à condição deEvent == "Start". O registro 6 é descartado sem afetar o estado ou a saída.
State:
| etapa | 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" |
Registro 7
| Ts | Event |
|---|---|
| 8m | "Start" |
Registre a avaliação em cada etapa:
-
s3: a verificação 1 não é passada porque o estado estás2vazio e a Verificação 2 não é passada porque não atende à condição deEvent == "Stop". -
s2: a verificação 1 não é passada porque o estado estás1vazio e a Verificação 2 não é passada porques2falta uma sequência ativa. -
s1: a verificação 1 não foi passada porque não há nenhuma etapa anterior. Ele passa a Verificação 2 porque atende à condição deEvent == "Start". Essa correspondência inicia uma nova sequência coms1um novom_id. O registro 7 e seum_id(1) são adicionados ao estado e à saída.
State:
| etapa | 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
Existem agora duas sequências ativas no estado.
Registro 8
| Ts | Event |
|---|---|
| 11m | "E" |
Registre a avaliação em cada etapa:
-
s3: a verificação 1 não é passada porque o estado estás2vazio e a Verificação 2 não é passada porque não atende às3condição deEvent == "Stop". -
s2: a verificação 1 é passada porque o estado nãos1está vazio e o registro atende à condição deTs - s1.Ts < 5m. Essa correspondência faz com que o estado des1seja limpo e a sequência ems1seja promovida paras2. O registro 8 e seum_id(1) são adicionados ao estado e à saída. -
s1: a verificação 1 é irrelevante porque não há nenhuma etapa anterior e a Verificação 2 não é passada porque o registro não atende à condição deEvent == "Start".
State:
| etapa | 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" |
Registro 9
| Ts | Event |
|---|---|
| 12m | "Stop" |
Registre a avaliação em cada etapa:
-
s3: a verificação 1 é passada porques2não está úmida e atende às3condição deEvent == "Stop". Essa correspondência faz com que o estado des2seja limpo e a sequência ems2seja promovida paras3. O registro 9 e seum_id(1) são adicionados ao estado e à saída. -
s2: a verificação 1 não é passada porque o estado estás1vazio e a Verificação 2 não é passada porques2falta uma sequência ativa. -
s1: a verificação 1 não foi passada porque não há nenhuma etapa anterior e a Verificação 2 não é passada porque o registro não atende à condição de Evento == "Iniciar".
State:
| etapa | 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" |
Saída final
| 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 |