Skip to main content

Pipe Operator (|)

Introduction

The Pipe Operator (|) in AQL is a syntactic construct designed to make query logic more readable and composable. It allows you to chain expressions and function calls sequentially.

Functionally, the operator takes the expression on the left and passes it as the first argument into the function on the right.

Basic Syntax: The below 2 are equivalent

// Pipe syntax (preferred)
users | avg(users.age)

// Standard syntax
avg(users, users.age)

Why use pipe?

Unlike SQL, which enforces a rigid declarative pattern (SELECT .. FROM .. WHERE .. GROUP BY ..), AQL is composable. Inspired by functional programming, the pipe operator allows you to break a complex query into smaller components and compose them together. This results in code that:

  • Matches your mental model: You read the query from left to right, following the flow of data.
  • Improves maintainability: Steps are decoupled and easier to debug.

Technical syntax

// Pipe syntax
expression | function_call(arg2, arg3)

// Equivalent to
function_call(expression, arg2, arg3)

Example

Let's calculate the Total Sales for Singapore using a standard E-commerce dataset.

Model orders {
dimension country {}
dimension total_value {}
}
Dataset ecommerce {
models: [orders]
}

We need to perform two specific operations:

  • filter(): To isolate orders from Singapore.
  • sum(): To calculate the total value of those specific orders.
filter(table_expr, filter condition) // -> Table
sum(table_expr, field_ref) // -> Number

By using the pipe operator, we can chain these operations to create a clear data pipeline:

orders | filter(orders.country = 'Singapore') | sum(orders.total_value)
  • Model orders is passed into filter()’s first argument. filter() apply the condition on it, and produce a new Table (let's call it filtered_orders)
  • Table filtered_orders is then piped into sum()'s first argument, and the function produces the final result.

In comparison, without the pipe operator, the code must be written "inside-out," which is significantly harder to read:

// Non-pipe version (Harder to read)
sum(filter(orders, orders.country = 'Singapore'), orders.total_value)

Let us know what you think about this document :)