Skip to content

05 — Read controls

Status: Draft
Applies to: JSON collection reads

MeshQL has one recursive JSON read protocol. Every collection node may carry local controls; collection responses use { items, pageInfo }.

{
"post": {
"$select": {
"id": true,
"title": true,
"comments": {
"$select": { "id": true, "body": true },
"$where": { "field": "body", "op": "like", "value": "%hello%" },
"$orderBy": [{ "field": "id", "direction": "desc" }],
"$page": { "first": 10 }
}
},
"$where": { "field": "status", "op": "eq", "value": "published" },
"$orderBy": [{ "field": "createdAt", "direction": "desc", "nulls": "last" }],
"$page": { "first": 20 }
}
}

Every read node uses $select. Fields outside $select and unknown $ keys MUST be rejected.

KeyApplies toMeaning
$selectall nodesField and relation selection
$wherecollection roots, many relationsBoolean filter tree
$orderBycollection roots, many relationsMulti-key sort
$pagecollection roots, many relationsForward keyset page (first, after)
$groupBycollection rootsGroup keys
$aggregatecollection rootsNamed aggregate projections
$havinggrouped collection rootsPost-aggregate filter
$distinctcollection rootsDistinct field list

$where, $orderBy, and $page on one relations MUST be rejected.

Operators: eq, ne, gt, gte, lt, lte, in, nin, like, ilike, isNull, isNotNull.

Boolean composition uses { "and": [...] }, { "or": [...] }, and { "not": ... }.

Collection:

{
"items": [],
"pageInfo": {
"hasNextPage": false,
"startCursor": null,
"endCursor": null
}
}

Point reads return an object or null.

Cursors are opaque. A server MUST reject a cursor whose entity, relation path, ordering, or query scope does not match the current read.

LimitValue
first default50
first max200
filter tree depth8
filter nodes64
in array size200
groupBy keys8
aggregate aliases16