Transform operators :: Kloudfuse Docs
Transform operators
FuseQL transform operators reshape the result set produced by earlier pipeline stages: bucketing events by time, removing duplicates, pivoting columns, and shifting rows.
backshift
Returns the value of a numeric field from N rows back in a time-ordered result set. The default shift is 1 row. Use backshift to compute period-over-period deltas — subtract the shifted value from the current value to get the change between consecutive time buckets.
Syntax
| backshift <field> [, <n>] [as <alias>]
Parameters
| Parameter | Required | Description |
|---|---|---|
<field> |
Required | The numeric field whose previous-row value is retrieved. |
<n> |
Optional | Number of rows to shift back. Defaults to 1. Use 2 to compare with two periods ago. |
as <alias> |
Optional | Output column name for the shifted value. Defaults to _backshift. |
Example
Count nginx requests per 1-minute bucket, shift by 1 row to get the previous minute’s count, and compute the per-minute delta.
source="nginx"
| timeslice 1m
| count as requests by _timeslice
| backshift requests, 1 as prev_requests
| (requests - prev_requests) as delta
| _timeslice | requests | prev_requests | delta |
|---|---|---|---|
| 2026-06-27 18:53:00 UTC | 61,441 | (null) | (null) |
| 2026-06-27 18:54:00 UTC | 650,712 | 61,441 | 589,271 |
| 2026-06-27 18:55:00 UTC | 474,040 | 650,712 | -176,672 |
dedup
Removes duplicate log lines from the result set, retaining only one row per unique combination of the specified fields. Optionally, keep the first N duplicate rows per group instead of just one. Use dedup to collapse repeated log events — for example, keeping only the first occurrence of each unique error message per source.
Syntax
| dedup by <field1>[, <field2>, ...]
| dedup <n> by <field1>[, <field2>, ...]
Parameters
| Parameter | Required | Description |
|---|---|---|
by <field1>, … |
Required | One or more fields that define uniqueness. Rows with the same values for all listed fields are considered duplicates. |
<n> |
Optional | Number of rows to keep per unique group. Defaults to 1 (keep only the first occurrence). |
Example
Parse nginx logs and keep only the first log line per unique combination of HTTP method and status code, eliminating repeated entries for the same method/status pair.
source="nginx"
| parse "* - - [*] \"* *\" * * *" as ip,date,method,url,status,bytes,rest
| dedup by method, status
| method | status | url |
|---|---|---|
| GET | 200 | /index.html |
| POST | 201 | /api/users |
| GET | 404 | /missing.html |
timeslice
Buckets each event’s timestamp into fixed-width time windows for use in time-series aggregation.
The bucket value is exposed as _timeslice (epoch milliseconds) and is the standard grouping field for log-based time-series aggregations.
Syntax
| timeslice <duration>
| timeslice <duration> as <alias>
<duration> accepts FuseQL duration literals such as 1m, 5m, 1h, 1d, 7d. When as <alias> is omitted, the bucket field is named _timeslice.
Examples
Count events per 5-minute bucket:
* | timeslice 5m | count by (_timeslice)
Group by an additional dimension to produce one series per source:
* | timeslice 1m | count by (_timeslice, source)
Use a custom alias for the bucket field:
* | timeslice 1m as bucket | count by (bucket, status_code)
To produce a time series, include _timeslice (or the alias) in the by clause. Without it, the aggregation collapses the entire query range into a single value:
* | count
* | timeslice 1m | count by (_timeslice)
Bucket alignment
Buckets are anchored to the Unix epoch (1970-01-01 00:00:00 UTC), not to a calendar week, month, or year. Boundaries fall at every multiple of <duration> measured from the epoch:
- Durations that evenly divide 24 hours (
1m,5m,15m,1h,4h,12h) align to UTC midnight, because UTC midnight is itself a multiple of the duration measured from the epoch. - Durations that do not divide 24 hours (
7h,13m) remain anchored to the epoch grid but their boundaries drift across the day — they do not land on UTC midnight. - Multi-day durations (
2d,7d,10d) follow the epoch grid, not calendar boundaries. Withtimeslice 7d, week boundaries always fall on a Thursday because 1970-01-01 was a Thursday.
transpose
Converts aggregate query results from a long format into a wide tabular format by pivoting row values into column headers. Similar to a pivot table, transpose transforms a long list of rows into a wide table, making it easier to compare values across dimensions — for example, displaying request counts per status code as separate columns across time.
Syntax
| transpose row <row_field1>[, <row_field2>, ...] column <column_field1>[, <column_field2>, ...]
Parameters
| Parameter | Required | Description |
|---|---|---|
row <row_field1>, … |
Required | One or more fields whose values become the row labels in the output table. |
column <column_field1>, … |
Required | One or more fields whose unique values become column headers in the output table. |
Example
Without transpose, the following query produces a long-format table that is difficult to read:
source="nginx"
| timeslice 5m
| count by _timeslice, status
With transpose, pivot the results to display status codes as columns and timeslices as rows:
source="nginx"
| timeslice 5m
| count by _timeslice, status
| transpose row _timeslice column status
| _timeslice | 200 | 404 | 500 |
|---|---|---|---|
| 2026-06-27 18:50:00 UTC | 412,840 | 1,203 | 87 |
| 2026-06-27 18:55:00 UTC | 389,120 | 987 | 62 |