7. Parameters, variables and explain
7.1 Parameters: $name
A query can reference named parameters. Their values travel next to the query:
{"query": "on users | where age >= $min and city in $cities | limit $n",
"params": {"min": 18, "cities": ["Paris", "Lyon"], "n": 10}}
Behavior
- Each
$nameoutside a string literal is replaced by the literal of its value before the query is authorized, planned or run. Strings are quoted and escaped, so a value never changes the structure of the query:$namebound tox" | deletestays one string. - Any JSON value works: numbers, strings, booleans,
null, arrays (forin), objects (forinsert). - A parameter goes wherever its literal could:
limit $n,near embedding, $vector,fill … from $start to $end. - An unbound
$namefails the request (variable $name is not bound; …); unused parameters are ignored. - From a terminal:
ogcli --param min=18 --param 'cities=["Paris","Lyon"]' '…'(a value is JSON when it parses, else a string). - Each distinct set of values is planned (and cached) on its own.
7.2 Variables: let
let <$name> = <expression> [, <$name> = <expression>]* | … | <source> | …
let <$name> ?= <expression> | …
let <$name> = ( <query> ) | …
Definition. Names a value computed once per query, before it runs.
let $threshold = 50, $since = parse_date("2026-02-01")
| on orders
| where price * qty > $threshold and parse_date(month) >= $since
| derive margin = price * qty - $threshold
Behavior
- Evaluated once per query, before planning, then used wherever
$nameappears.let $now = now()gives every row the same instant. - A value may use any function, request parameters, and variables declared before it (
let $max = $min * 2, or a laterletheader). It cannot read document fields:let $x = qtyis refused (cannot depend on documents). - A name is bound once: redeclaring a variable, or declaring a name also given in
params, is an error. ?=binds a default: only when the name is not bound already (byparams, an earlier variable, or the query reading the view). This is how a view gives its parameters default values:let $gran ?= "month" | ….- Variables are bound like parameters, as escaped literals:
explain let $n = 2 | on orders | limit $nshowslimit 2.
Query variables
A value written as a query in parentheses is the array of its rows, read once in the scope of the request:
let $settings = (on settings | limit 1)
| let $opening = get(at($settings, 0), "opening")
| on ledger | where month >= $opening
- The query may use the variables before it and read views.
- It must only read, and returns at most 1,000 rows (
a query in let returns at most 1000 rows). - It runs through
query.execute(in a Place), likeon view.
7.3 explain
explain <query>
Definition. Plans a query without running it and returns one document describing the plan. Authorization is the same as for the query itself.
explain on orders | where qty > 1 | sort price * qty desc | limit 3
{"access":"collection_scan","collection":"orders","executor":"governed_blocking","mode":"governed_blocking",
"operators":[{"detail":"qty > 1","stage":"filter"},{"detail":"__og_sort_0 = price * qty","stage":"derive"},
{"detail":"__og_sort_0 desc","stage":"sort"},{"detail":"__og_sort_0","stage":"drop"},{"detail":"3","stage":"limit"}],
"read_only":true}
| Field | Meaning |
|---|---|
access | collection_scan or primary_key_lookup |
executor | streaming, governed_blocking, transactional (writes), or rejected when no bounded executor fits |
mode | The memory contract of the plan |
operators | The physical operators in order, shorthand forms expanded, filters where the planner moved them |
read_only | Whether the plan writes |
explain define view … checks a view definition without writing it. explain shows views expanded and
parameters bound, so it is the tool to see what a view really runs.