from_collection
from_collection is the simplest projection strategy. It compiles to a scan, filter, sort, and page over a single collection.
Compiles to: scan → filter → sort → page
Use this strategy when you need a filtered and sorted list from one collection with no joins or computed metrics.
Example
domain:
projections:
latest_messages:
strategy: from_collection
collection: hello_messages
where:
"==":
- var: row.user_id
- var: principal.subject
search:
arg: q
fields: [message]
sort:
by_arg: sort_by
order_arg: sort_order
allowed: [created_at, message]
default_by: created_at
default_order: desc
pagination:
mode: page
page_arg: page
page_size_arg: page_size
default_page_size: 10
max_page_size: 50
collection
The collection field names the single collection this projection scans. All fields on the collection are included in the result unless the query layer applies additional shaping.
where
where is an optional $expr rule applied to each row before it is returned. Rows that do not match are excluded.
where:
and:
- "==":
- var: row.user_id
- var: principal.subject
- "!==":
- var: row.moderation.status
- rejected
row.* refers to fields on the collection record. principal.subject is the authenticated caller's identity.
When where is omitted, the projection returns all rows in the collection.
search
search adds full-text filtering across one or more fields. The caller passes a query string via the named input arg.
search:
arg: q
fields: [message, title]
arg names the input argument that carries the search query. fields lists the collection fields to search. Full-text matching semantics (tokenization, case sensitivity) are determined by the provider.
When search is omitted, no full-text filtering is available on this projection.
sort
sort:
by_arg: sort_by
order_arg: sort_order
allowed: [created_at, message]
default_by: created_at
default_order: desc
| Field | Required | Description |
|---|---|---|
default_by | Yes | Field to sort by when no sort arg is supplied |
default_order | Yes | asc or desc when no order arg is supplied |
by_arg | No | Input arg name that selects the sort field |
order_arg | No | Input arg name that selects asc or desc |
allowed | When by_arg is set | Allowlist of fields the caller may sort by |
If by_arg is omitted, the sort is fixed to default_by and default_order. The caller cannot change it.
If by_arg is provided but a caller passes a field not in allowed, the runtime rejects the request.
pagination
pagination:
mode: page
page_arg: page
page_size_arg: page_size
default_page_size: 10
max_page_size: 50
mode: page is the only supported mode. The projection returns a page of results and a total count.
| Field | Required | Description |
|---|---|---|
page_arg | Yes | Input arg name for the requested page number (1-indexed) |
page_size_arg | Yes | Input arg name for the number of rows per page |
default_page_size | Yes | Page size used when page_size_arg is not supplied |
max_page_size | Yes | Maximum page size a caller may request |
The runtime enforces max_page_size. A caller requesting more rows than the maximum receives the maximum.
Accessing session state
where and sort expressions have access to principal.* but not to session.*. Session state is user-scoped and request-scoped. Projections are not session-aware — they are stateless read views.
If you need session-influenced filtering, pass the relevant session value as an explicit query input and use it in the where clause.