spl-to-apl

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SPL to APL Translator

SPL 转 APL 转换器

Type safety: Fields like status are often stored as strings. Always cast before numeric comparison: toint(status) >= 500, not status >= 500.

类型安全:像status这类字段通常以字符串形式存储。进行数值比较前务必先转换类型:使用toint(status) >= 500,而非status >= 500。

Critical Differences

关键差异

  1. Time is explicit in APL: SPL time pickers don't translate — add
    where _time between (ago(1h) .. now())
  2. Structure: SPL
    index=... | command
    → APL
    ['dataset'] | operator
  3. Join is preview: limited to 50k rows, inner/innerunique/leftouter only
  4. cidrmatch args reversed: SPL
    cidrmatch(cidr, ip)
    → APL
    ipv4_is_in_range(ip, cidr)

  1. APL中时间需显式声明:SPL的时间选择器无法直接转换——需添加
    where _time between (ago(1h) .. now())
  2. 结构差异:SPL
    index=... | command
    → APL
    ['dataset'] | operator
  3. Join为预览功能:限制最多50k行,仅支持inner/innerunique/leftouter类型
  4. cidrmatch参数顺序反转:SPL
    cidrmatch(cidr, ip)
    → APL
    ipv4_is_in_range(ip, cidr)

Core Command Mappings

核心命令映射

SPLAPLNotes
search index=...
['dataset']
Dataset replaces index
search field=value
where field == "value"
Explicit where
where
where
Same
stats
summarize
Different aggregation syntax
eval
extend
Create/modify fields
table
/
fields
project
Select columns
fields -
project-away
Remove columns
rename x as y
project-rename y = x
Rename
sort
/
sort -
order by ... asc/desc
Sort
head N
take N
Limit rows
top N field
summarize count() by field | top N by count_
Two-step
dedup field
summarize arg_max(_time, *) by field
Keep latest
rex
parse
or
extract()
Regex extraction
join
join
Preview feature
append
union
Combine datasets
mvexpand
mv-expand
Expand arrays
timechart span=X
summarize ... by bin(_time, X)
Manual binning
rare N field
summarize count() by field | order by count_ asc | take N
Bottom N
spath
parse_json()
or
json['path']
JSON access
transaction
No direct equivalentUse summarize + make_list
Complete mappings:
reference/command-mapping.md

SPLAPL说明
search index=...
['dataset']
Dataset替代index
search field=value
where field == "value"
显式使用where
where
where
用法一致
stats
summarize
聚合语法不同
eval
extend
创建/修改字段
table
/
fields
project
选择列
fields -
project-away
删除列
rename x as y
project-rename y = x
重命名字段
sort
/
sort -
order by ... asc/desc
排序
head N
take N
限制行数
top N field
summarize count() by field | top N by count_
分两步实现
dedup field
summarize arg_max(_time, *) by field
保留最新记录
rex
parse
or
extract()
正则提取
join
join
预览功能
append
union
合并数据集
mvexpand
mv-expand
展开数组
timechart span=X
summarize ... by bin(_time, X)
手动分箱
rare N field
summarize count() by field | order by count_ asc | take N
获取底部N条
spath
parse_json()
or
json['path']
JSON访问
transaction
无直接等效命令使用summarize + make_list替代
完整映射列表:
reference/command-mapping.md

Stats → Summarize

Stats → Summarize

undefined
undefined

SPL

SPL

| stats count by status
| stats count by status

APL

APL

| summarize count() by status
undefined
| summarize count() by status
undefined

Key function mappings

核心函数映射

SPLAPL
count
count()
count(field)
countif(isnotnull(field))
dc(field)
dcount(field)
avg/sum/min/max
Same
median(field)
percentile(field, 50)
perc95(field)
percentile(field, 95)
first/last
arg_min/arg_max(_time, field)
list(field)
make_list(field)
values(field)
make_set(field)
SPLAPL
count
count()
count(field)
countif(isnotnull(field))
dc(field)
dcount(field)
avg/sum/min/max
用法一致
median(field)
percentile(field, 50)
perc95(field)
percentile(field, 95)
first/last
arg_min/arg_max(_time, field)
list(field)
make_list(field)
values(field)
make_set(field)

Conditional count pattern

条件计数示例

undefined
undefined

SPL

SPL

| stats count(eval(status>=500)) as errors by host
| stats count(eval(status>=500)) as errors by host

APL

APL

| summarize errors = countif(status >= 500) by host

Complete function list: `reference/function-mapping.md`

---
| summarize errors = countif(status >= 500) by host

完整函数列表:`reference/function-mapping.md`

---

Eval → Extend

Eval → Extend

undefined
undefined

SPL

SPL

| eval new_field = old_field * 2
| eval new_field = old_field * 2

APL

APL

| extend new_field = old_field * 2
undefined
| extend new_field = old_field * 2
undefined

Key function mappings

核心函数映射

SPLAPLNotes
if(c, t, f)
iff(c, t, f)
Double 'f'
case(c1,v1,...)
case(c1,v1,...,default)
Requires default
len(str)
strlen(str)
lower/upper
tolower/toupper
substr
substring
0-indexed in APL
replace
replace_string
tonumber
toint/tolong/toreal
Explicit types
match(s,r)
s matches regex "r"
Operator
split(s, d)
split(s, d)
Same
mvjoin(mv, d)
strcat_array(arr, d)
Join array
mvcount(mv)
array_length(arr)
Array length
SPLAPL说明
if(c, t, f)
iff(c, t, f)
多一个'f'
case(c1,v1,...)
case(c1,v1,...,default)
必须包含默认值
len(str)
strlen(str)
lower/upper
tolower/toupper
substr
substring
APL中为0起始索引
replace
replace_string
tonumber
toint/tolong/toreal
显式指定类型
match(s,r)
s matches regex "r"
使用运算符形式
split(s, d)
split(s, d)
用法一致
mvjoin(mv, d)
strcat_array(arr, d)
数组合并为字符串
mvcount(mv)
array_length(arr)
数组长度

Case statement pattern

Case语句示例

undefined
undefined

SPL

SPL

| eval level = case( status >= 500, "error", status >= 400, "warning", 1==1, "ok" )
| eval level = case( status >= 500, "error", status >= 400, "warning", 1==1, "ok" )

APL

APL

| extend level = case( status >= 500, "error", status >= 400, "warning", "ok" )

Note: SPL's `1==1` catch-all becomes implicit default in APL.

---
| extend level = case( status >= 500, "error", status >= 400, "warning", "ok" )

注意:SPL中用`1==1`作为兜底条件,在APL中是隐式默认值。

---

Rex → Parse/Extract

Rex → Parse/Extract

undefined
undefined

SPL

SPL

| rex field=message "user=(?<username>\w+)"
| rex field=message "user=(?<username>\w+)"

APL - parse with regex

APL - 正则解析

| parse kind=regex message with @"user=(?P<username>\w+)"
| parse kind=regex message with @"user=(?P<username>\w+)"

APL - extract function

APL - 提取函数

| extend username = extract("user=(\w+)", 1, message)
undefined
| extend username = extract("user=(\w+)", 1, message)
undefined

Simple pattern (non-regex)

简单模式(非正则)

undefined
undefined

SPL

SPL

| rex field=uri "^/api/(?<version>v\d+)/(?<endpoint>\w+)"
| rex field=uri "^/api/(?<version>v\d+)/(?<endpoint>\w+)"

APL

APL

| parse uri with "/api/" version "/" endpoint

---
| parse uri with "/api/" version "/" endpoint

---

Time Handling

时间处理

SPL time pickers don't translate. Always add explicit time range:
undefined
SPL的时间选择器无法直接转换,务必添加显式时间范围:
undefined

SPL (time picker: Last 24 hours)

SPL(时间选择器:最近24小时)

index=logs
index=logs

APL

APL

['logs'] | where _time between (ago(24h) .. now())
undefined
['logs'] | where _time between (ago(24h) .. now())
undefined

Timechart translation

Timechart转换

undefined
undefined

SPL

SPL

| timechart span=5m count by status
| timechart span=5m count by status

APL

APL

| summarize count() by bin(_time, 5m), status

---
| summarize count() by bin(_time, 5m), status

---

Common Patterns

常见模式示例

Error rate calculation

错误率计算

undefined
undefined

SPL

SPL

| stats count(eval(status>=500)) as errors, count as total by host | eval error_rate = errors/total*100
| stats count(eval(status>=500)) as errors, count as total by host | eval error_rate = errors/total*100

APL

APL

| summarize errors = countif(status >= 500), total = count() by host | extend error_rate = toreal(errors) / total * 100
undefined
| summarize errors = countif(status >= 500), total = count() by host | extend error_rate = toreal(errors) / total * 100
undefined

Subquery (subsearch)

子查询(subsearch)

undefined
undefined

SPL

SPL

index=logs [search index=errors | fields user_id | format]
index=logs [search index=errors | fields user_id | format]

APL

APL

let error_users = ['errors'] | where _time between (ago(1h) .. now()) | distinct user_id; ['logs'] | where _time between (ago(1h) .. now()) | where user_id in (error_users)
undefined
let error_users = ['errors'] | where _time between (ago(1h) .. now()) | distinct user_id; ['logs'] | where _time between (ago(1h) .. now()) | where user_id in (error_users)
undefined

Join datasets

数据集关联

undefined
undefined

SPL

SPL

| join user_id [search index=users | fields user_id, name]
| join user_id [search index=users | fields user_id, name]

APL

APL

| join kind=inner (['users'] | project user_id, name) on user_id
undefined
| join kind=inner (['users'] | project user_id, name) on user_id
undefined

Transaction-like grouping

类Transaction分组

undefined
undefined

SPL

SPL

| transaction session_id maxspan=30m
| transaction session_id maxspan=30m

APL (no direct equivalent — reconstruct with summarize)

APL(无直接等效命令——用summarize重构)

| summarize start_time = min(_time), end_time = max(_time), events = make_list(pack("time", _time, "action", action)), duration = max(_time) - min(_time) by session_id | where duration <= 30m

---
| summarize start_time = min(_time), end_time = max(_time), events = make_list(pack("time", _time, "action", action)), duration = max(_time) - min(_time) by session_id | where duration <= 30m

---

String Matching Performance

字符串匹配性能对比

SPLAPLSpeed
field="value"
field == "value"
Fastest
field="*value*"
field contains "value"
Moderate
field="value*"
field startswith "value"
Fast
match(field, regex)
field matches regex "..."
Slowest
Prefer
has
over
contains
(word-boundary matching is faster). Use
_cs
variants for case-sensitive (faster).

SPLAPL速度
field="value"
field == "value"
最快
field="*value*"
field contains "value"
中等
field="value*"
field startswith "value"
match(field, regex)
field matches regex "..."
最慢
优先使用
has
而非
contains
(词边界匹配速度更快)。如需区分大小写,使用
_cs
变体(速度更快)。

Reference

参考资料

  • reference/command-mapping.md
    — complete command list
  • reference/function-mapping.md
    — complete function list
  • reference/examples.md
    — full query translation examples
  • APL docs: https://axiom.co/docs/apl/introduction
  • reference/command-mapping.md
    — 完整命令列表
  • reference/function-mapping.md
    — 完整函数列表
  • reference/examples.md
    — 完整查询转换示例
  • APL官方文档:https://axiom.co/docs/apl/introduction